angrybeanie_wagtail/env/lib/python3.12/site-packages/wagtail/admin/models.py
2025-07-25 21:32:16 +10:00

102 lines
3.6 KiB
Python

from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import Count
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from modelcluster.fields import ParentalKey
from taggit.models import Tag
# The panels module extends Page with some additional attributes required by
# wagtail admin (namely, base_form_class and get_edit_handler). Importing this within
# wagtail.admin.models ensures that this happens in advance of running wagtail.admin's
# system checks.
from wagtail.admin import panels # NOQA: F401
from wagtail.models import Page
# A dummy model that exists purely to attach the access_admin permission type to, so that it
# doesn't get identified as a stale content type and removed by the remove_stale_contenttypes
# management command.
class Admin(models.Model):
class Meta:
default_permissions = [] # don't create the default add / change / delete / view perms
permissions = [
("access_admin", _("Can access Wagtail admin")),
]
def get_object_usage(obj):
"""Returns a queryset of pages that link to a particular object"""
pages = Page.objects.none()
# get all the relation objects for obj
relations = [
f
for f in type(obj)._meta.get_fields(include_hidden=True)
if (f.one_to_many or f.one_to_one) and f.auto_created
]
for relation in relations:
related_model = relation.related_model
# if the relation is between obj and a page, get the page
if issubclass(related_model, Page):
pages |= Page.objects.filter(
id__in=related_model._base_manager.filter(
**{relation.field.name: obj.id}
).values_list("id", flat=True)
)
else:
# if the relation is between obj and an object that has a page as a
# property, return the page
for f in related_model._meta.fields:
if isinstance(f, ParentalKey) and issubclass(
f.remote_field.model, Page
):
pages |= Page.objects.filter(
id__in=related_model._base_manager.filter(
**{relation.field.name: obj.id}
).values_list(f.attname, flat=True)
)
return pages
def popular_tags_for_model(model, count=10):
"""Return a queryset of the most frequently used tags used on this model class"""
content_type = ContentType.objects.get_for_model(model)
return (
Tag.objects.filter(taggit_taggeditem_items__content_type=content_type)
.annotate(item_count=Count("taggit_taggeditem_items"))
.order_by("-item_count")[:count]
)
class EditingSession(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="editing_sessions",
)
content_type = models.ForeignKey(
ContentType, on_delete=models.CASCADE, related_name="+"
)
object_id = models.CharField(max_length=255)
content_object = GenericForeignKey(
"content_type", "object_id", for_concrete_model=False
)
last_seen_at = models.DateTimeField()
is_editing = models.BooleanField(default=False)
@staticmethod
def cleanup():
EditingSession.objects.filter(
last_seen_at__lt=timezone.now() - timezone.timedelta(hours=1)
).delete()
class Meta:
indexes = [
models.Index(fields=["content_type", "object_id"]),
]