Site icon JnPnote

Django-Activity-Stream Practice

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.

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

1. Prerequisites

2. Start a Project

mkdir dj-activity-stream-practice
cd dj-activity-stream-practice
python -m virtualenv venv
source venv/bin/activate
venv/Scripts/activate # for Windows
pip install django=="specific version"
pip install django # without version install the latest
django-admin startproject activity_stream .
python manage.py migrate
python manage.py createsuperuser

3. Create Login Page

python manage.py startapp accounts
INSTALLED_APPS = [
    # other apps
    "accounts",
]

TEMPLATES = [
    {
        "DIRS": [BASE_DIR / "templates"],
    },
]
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")),
]
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"),
]
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")
<!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 %}
{% 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 %}

4. Create Dashboard Page

python manage.py startapp dashboards
INSTALLED_APPS = [
    # other apps
    "accounts",
    "dashboards",
]
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")),
]
from django.urls import path
from django.views.generic.base import TemplateView

urlpatterns = [
    path("", TemplateView.as_view(template_name="dashboards/dashboard.html"), name="dashboard"),
]
{% 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 %}
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")

5. Install django-activity-stream package and settings

pip install django-activity-stream
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,
}

6. Update Dashboard

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)
python manage.py migrate
from .managers import MyActionManager
from actstream.models import Action


class MyAction(Action):
    objects = MyActionManager()

    class Meta:
        proxy = True
python manage.py makemigrations
python manage.py migrate
from django.contrib import admin
from .models import MyAction


admin.site.register(MyAction)
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"))
default_app_config = "dashboards.apps.DashboardsConfig"
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()
from django.urls import path
from dashboards import views

urlpatterns = [
    path("", views.MyActionStreamView.as_view(), name="dashboard"),
]
  <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>

Thank you for reading my post!

Exit mobile version