Skip to content
JnPnote
  • Home
  • Jisoo
    • Christianity
      • Bible verses
      • My Journal
      • Writing Entire Bible
    • Coding
      • CS50
      • Swift
      • Git
      • Python
        • Django
        • scrape
      • Docker-Compose
      • HTML
      • React
      • RPi
    • Coffee
      • latte art
    • Travel
    • Woodworking
  • Pimpawee
    • Cookit
    • Drawing
    • Restaurant review
  • Sean
    • Baby Book for Sean
  • New Born
    • baby book for new born
  • Gallery
  • Contact Us
  • ไทย
    • English
    • 한국어

Django-Activity-Stream Practice

May 12, 2023 / By jisoooh0202 / Coding, จีซู, Django, Python

Usually, I could find tutorials or instructions for the real cases. But not this package. I couldn’t find any of blogs or videos using this package to show on UI. Also, I needed myself using separate app structure. So, I decided to write my own.

Please note that there won’t be a lot of explanation of code. This post will be just the step by step to build.

Using Ubuntu 22.04.2 at the moment writing this.

  • Prerequisites
  • Start a Project
  • Create Login Page
  • Create Dashboard Page
  • Install django-activity-stream package and settings
  • Update Dashboard

If you just need to know how to setup the package, jump to here.

1. Prerequisites

  • VSCode or other IDE installed.
  • Python installed.
  • pip installed.
  • I am assuming it would be read by someone who has some knowledge of programming, python and django. Just in case you are a very beginner, please see this or this post for how to start a django project little more detail.

2. Start a Project

  • create a new directory for the project
  • create virtual environment
mkdir dj-activity-stream-practice
cd dj-activity-stream-practice
python -m virtualenv venv
  • activate virtualenv
source venv/bin/activate
venv/Scripts/activate # for Windows
  • install Django in the virtual environment
pip install django=="specific version"
pip install django # without version install the latest
  • start django project
django-admin startproject activity_stream .
  • create database and super user
python manage.py migrate
python manage.py createsuperuser

3. Create Login Page

  • You might not need this step, but I do it for myself to practice creating separate app.
  • However, we need login and out to get the user login/out activity
  • Here is another way to create login page.
  • create an accounts app first with bash script
python manage.py startapp accounts
  • open up the VSCode or any other IDE you prefer.
  • update settings
INSTALLED_APPS = [
    # other apps
    "accounts",
]

TEMPLATES = [
    {
        "DIRS": [BASE_DIR / "templates"],
    },
]
  • update project urls.py to link (or point?) urls to accounts app
from django.contrib import admin
from django.urls import include, path
from django.views.generic.base import TemplateView

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", TemplateView.as_view(template_name="home.html"), name="home"),
    path("accounts/", include("accounts.urls")),
]
  • You can go to localhost:8000/accounts/ to login. However, you will get “page not found” error when you go to localhost:8000. that’s why we need the second path to home.html is needed.
  • create urls.py file under accounts app
from django.urls import path
from accounts import views

urlpatterns = [
    path("", views.home, name="home"),
    path("login/", views.login_view, name="login"),
    path("logout/", views.logout_view, name="logout"),
]
  • update accounts/views.py
from django.shortcuts import render, redirect
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login, logout


def home(request):
    return render(request, "home.html")

def login_view(request):
    if request.method == "POST":
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            user = form.get_user()
            login(request, user)
            return redirect("home")
    else:
        form = AuthenticationForm()
    return render(request, "accounts/login.html", {"form": form})


def logout_view(request):
    logout(request)
    return redirect("home")
  • create templates directory on root directory and create base.html and home.html in it.
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>{% block title %}Django{% endblock %}</title>
</head>
<body>
  <main>
    {% block content %}
    {% endblock %}
  </main>
</body>
</html>
{% extends 'base.html' %}

{% block title %}Home{% endblock %}

{% block content %}
{% if user.is_authenticated %}
  Hi {{ user.username }}!
  <p><a href="{% url 'logout' %}">Log Out</a></p>
{% else %}
  <p>You are not logged in</p>
  <a href="{% url 'login' %}">Log In</a>
{% endif %}
{% endblock %}
  • create accounts directory in templates, and create login.html
{% extends 'base.html' %}

{% block title %}Login{% endblock %}

{% block content %}
<h2>Log In</h2>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Log In</button>
</form>
{% endblock %}
  • runserver and test if you can login with super user account.
  • to test more, create one or more regular users on django admin page.
  • to go to django admin page, go to localhost:8000/admin/

4. Create Dashboard Page

  • stop the server or start new terminal
  • create a new app name dashboards through the terminal
python manage.py startapp dashboards
  • add dashboard app on the settings.py
INSTALLED_APPS = [
    # other apps
    "accounts",
    "dashboards",
]
  • add dashboards app to project urls.py
from django.contrib import admin
from django.urls import include, path
from django.views.generic.base import TemplateView

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", TemplateView.as_view(template_name="home.html"), name="home"),
    path("accounts/", include("accounts.urls")),
    path("dashboard/", include("dashboards.urls")),
]
  • create urls.py under dashboards app
from django.urls import path
from django.views.generic.base import TemplateView

urlpatterns = [
    path("", TemplateView.as_view(template_name="dashboards/dashboard.html"), name="dashboard"),
]
  • create dashboards folder under templates and create dashboard.html file
{% extends 'base.html' %}

{% block title %}Home{% endblock %}

{% block content %}
{% if user.is_authenticated %}
  
  <h1>Welcome to the Dashboard</h1>
  <p>Hello, {{ user.username }}!</p>
  <p>This is your dashboard content.</p>

  <p><a href="{% url 'logout' %}">Log Out</a></p>
{% else %}
  <p>You are not logged in</p>
  <a href="{% url 'login' %}">Log In</a>
{% endif %}
{% endblock %}
  • runserver if you stopped, login and go to localhost:8000/dashboard to check.
  • update the accounts/views.py to redirect to dashboard after logged in
from django.shortcuts import render, redirect
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login, logout


def home(request):
    return render(request, "home.html")


# point to dashboard url
def dashboard(request):
    return render(request, "dashboards/dashboard.html")


def login_view(request):
    if request.method == "POST":
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            user = form.get_user()
            login(request, user)
            return redirect("dashboard") # redirect to dashboard
    else:
        form = AuthenticationForm()
    return render(request, "accounts/login.html", {"form": form})


def logout_view(request):
    logout(request)
    return redirect("home")
  • check again if it is redirecting to dashboard or not

5. Install django-activity-stream package and settings

  • Install django-activity-stream package on the terminal
  • make sure the venv is activated
pip install django-activity-stream
  • update the settings.py
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "dashboards",
    "actstream",
]

SITE_ID=1

ACTSTREAM_SETTINGS = {
    "MANAGER": "dashboards.managers.MyActionManager",
    "FETCH_RELATIONS": True,
    "USE_PREFETCH": True,
    "USE_JSONFIELD": True,
    "GFK_FETCH_DEPTH": 1,
}
  • if you are still running server, you will get errors, maybe ImportError.
  • If you are not running the server, don’t worry and just follow the steps below.

6. Update Dashboard

  • create managers.py under dashboards app
from actstream.managers import ActionManager
from django.contrib.auth.signals import (
    user_logged_in,
    user_logged_out,
    user_login_failed,
)
from actstream import action
from django.dispatch import receiver


class MyActionManager(ActionManager):
    @receiver(user_logged_in)
    def track_login(sender, request, user, **kwargs):
        action.send(user, verb="logged in")
        print(
            "user {} logged in through page {}".format(
                user.username, request.META.get("HTTP_REFERER")
            )
        )

    @receiver(user_logged_out)
    def track_logout(sender, request, user, **kwargs):
        action.send(user, verb="logged out")
        print(
            "user {} logged out through page {}".format(
                user.username, request.META.get("HTTP_REFERER")
            )
        )

    @receiver(user_login_failed)
    def track_login_failed(sender, request, user, **kwargs):
        action.send(user, verb="login failed")
        print(
            "user {} failed to log in through page {}".format(
                user.username, request.META.get("HTTP_REFERER")
            )
        )

    user_logged_in.connect(track_login)
    user_logged_out.connect(track_logout)
    user_login_failed.connect(track_login_failed)
  • Again, If your server is running, you will get instruction to migrate. in case you don’t see them, but getting other errors, you might misspelled something.
  • again, if you are not running the server, just follow the steps below.
  • then, migrate.
python manage.py migrate
  • run server if you are not running, go to localhost:8000/admin
  • you will see ACTIVITY STREAMS app there.
  • update dashboards/models.py
from .managers import MyActionManager
from actstream.models import Action


class MyAction(Action):
    objects = MyActionManager()

    class Meta:
        proxy = True
  • Since we update the models.py, we need to update the database again.
python manage.py makemigrations
python manage.py migrate
  • update dashboards/admin.py to show MyAction model on django admin.
from django.contrib import admin
from .models import MyAction


admin.site.register(MyAction)
  • update dashboards/apps.py
  • You can find the description of this on the package docs
from django.apps import AppConfig


class DashboardsConfig(AppConfig):
    name = "dashboards"

    def ready(self):
        from actstream import registry
        from django.contrib.auth.models import User

        registry.register(User, self.get_model("MyAction"))
  • I got errors because imports all at first, and found the solution here.
  • update dashboards/__init.py__
  • I tested without this, and it worked fine. But this is in the package docs, so better to have it. maybe?
default_app_config = "dashboards.apps.DashboardsConfig"
  • update dashboards/views.py
from django.views import generic
from .models import MyAction


class MyActionStreamView(generic.ListView):
    model = MyAction
    template_name = "dashboards/dashboard.html"
    context_object_name = "action_list"

    def get_queryset(self):
        # Use custom manager methods or filters for CustomActionManagerOne
        return MyAction.objects.all()
  • update dashboards/urls.py
from django.urls import path
from dashboards import views

urlpatterns = [
    path("", views.MyActionStreamView.as_view(), name="dashboard"),
]
  • update templates/dashboards/dashboard.html
  <h2>Activity</h2>
  <ul>
    {% for activity in action_list %}
      <li>{{ activity.actor }} {{ activity.verb }} at {{ activity.timestamp }}</li>
    {% empty %}
      <li>No recent activities.</li>
    {% endfor %}
  </ul>
  • Now, go to localhost:8000/dashboard to check if you see your login/out activity.
  • test with other test users.
  • You can see both admin and test user’s logs. we can use permission or maybe the package’s filter function to make it show for certain user. I won’t go over that in this post though.
  • Done!!!
  • If you want to see the full code, here is the github repo.

Thank you for reading my post!

Related Posts:

  • coding
    Scrape practice with Beautiful Soup - Part 1
  • coding
    Scrape practice with Beautiful Soup – Part 2

Post navigation

How to Setup Port Forward for local Raspberry Pi Server
Build Django project with Cookiecutter
Gogo developed by ThemeHunk