v0.141.0
 1from plain.admin.cards import Card, TrendCard
 2from plain.admin.views import (
 3    AdminModelDetailView,
 4    AdminModelListView,
 5    AdminViewset,
 6    register_viewset,
 7)
 8
 9from .models import Pageview
10
11
12class PageviewsTrendCard(TrendCard):
13    title = "Pageviews trend"
14    model = Pageview
15    datetime_field = "timestamp"
16    size = TrendCard.Sizes.FULL
17    group_field = "source"
18    group_labels = {"": "Direct"}
19    aggregates = ("sum", "avg")
20
21
22@register_viewset
23class PageviewAdmin(AdminViewset):
24    class ListView(AdminModelListView):
25        model = Pageview
26        nav_section = "Pageviews"
27        nav_icon = "eye"
28        title = "Pageviews"
29        description = "Page visits with UTM tracking and session attribution."
30        fields = ["user_id", "url", "source", "timestamp", "session_id"]
31        search_fields = ["id", "user_id", "url", "session_id", "source", "medium"]
32        cards = [PageviewsTrendCard]
33
34    class DetailView(AdminModelDetailView):
35        model = Pageview
36
37
38class UserPageviewsCard(Card):
39    title = "Recent pageviews"
40    template_name = "pageviews/card.html"
41
42    def get_template_context(self) -> dict:
43        context = super().get_template_context()
44
45        # self.view has an object attribute when used in DetailView context
46        context["pageviews"] = Pageview.query.filter(
47            user_id=self.view.object.id  # ty: ignore[unresolved-attribute]
48        ).order_by("-timestamp")[:50]
49
50        return context