Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
dj-kaos-utils / admin.py
Size: Mime:
import threading

from django.contrib import admin
from django.contrib.admin.options import BaseModelAdmin, InlineModelAdmin
from django.db.models import Count
from django.utils.safestring import mark_safe


class EditReadonlyAdminMixin(BaseModelAdmin):
    edit_readonly_fields = ()

    def get_edit_readonly_fields(self, request, obj=None):
        return self.edit_readonly_fields

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = super().get_readonly_fields(request, obj)
        if obj:  # editing an existing object
            return self.get_edit_readonly_fields(request, obj) + readonly_fields
        return readonly_fields


class SluggableAdminMixin(EditReadonlyAdminMixin):
    slug_source = None

    def get_edit_readonly_fields(self, request, obj=None):
        return super().get_edit_readonly_fields(request, obj) + ('slug',)

    def get_prepopulated_fields(self, request, obj=None):
        assert self.slug_source
        prepopulated_fields = super().get_prepopulated_fields(request, obj)
        if obj:  # editing an existing object
            return prepopulated_fields
        return {**prepopulated_fields, 'slug': (self.slug_source,)}


def render_anchor_tag(href, text=None, blank=True):
    target_blank = '''target="_blank"''' if blank else ''
    return mark_safe(f"""
        <a {target_blank} href={href}>
            {text or href}
        <a/>
    """)


def anchor_tag(obj, link_field):
    if obj.pk:
        return render_anchor_tag(getattr(obj, link_field))
    return ""


class LinkableAdminMixin(BaseModelAdmin):
    link_fields = ()

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = super().get_readonly_fields(request, obj)
        if obj:
            for link_field in self.link_fields:
                f = lambda x: anchor_tag(x, link_field)
                f.__name__ = link_field
                setattr(self, link_field, f)
            return (*readonly_fields, *self.link_fields)
        return readonly_fields


# From https://gist.github.com/rafen/eff7adae38903eee76600cff40b8b659
class NoQSActionsAdminMixin(BaseModelAdmin):
    """
    Admin mixin enables actions that can be executed with no items selected on the admin change list.
    """

    extended_actions = []

    def changelist_view(self, request, extra_context=None):
        # if a extended action is called and there's no checkbox selected, select one with
        # invalid id, to get an empty queryset
        if 'action' in request.POST and request.POST['action'] in self.extended_actions:
            if not request.POST.getlist(admin.ACTION_CHECKBOX_NAME):
                post = request.POST.copy()
                post.update({admin.ACTION_CHECKBOX_NAME: 0})
                request._set_post(post)
        return super().changelist_view(request, extra_context)


def admin_action_message(count, errors_count, success_msg, error_msg):
    success_count = count - errors_count
    message = ""
    if success_count:
        message += success_msg.format(success_count)
    if errors_count:
        if message:
            message += " "
        message += error_msg.format(errors_count)
    return message


class AddInlineMixin(InlineModelAdmin):
    def get_queryset(self, request):
        queryset = super().get_queryset(request)
        return queryset.none()  # no existing records will appear


class ListInlineMixin(InlineModelAdmin):
    def has_add_permission(self, request, obj):
        return False


class ReadOnlyInlineMixin(ListInlineMixin):
    def has_change_permission(self, request, obj=None):
        return False


class AutoUserAdmin(admin.ModelAdmin):
    user_field = None

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        field = super().formfield_for_foreignkey(db_field, request, **kwargs)
        if db_field.name == self.user_field and field.initial is None:
            field.initial = request.user
        return field


class ModelAdminRequestMixin(object):
    """
    from https://stackoverflow.com/a/50380461/1437754
    """
    def __init__(self, *args, **kwargs):
        # let's define this so there's no chance of AttributeErrors
        self._request_local = threading.local()
        self._request_local.request = None
        super(ModelAdminRequestMixin, self).__init__(*args, **kwargs)

    def get_request(self):
        return self._request_local.request

    def set_request(self, request):
        self._request_local.request = request

    def changeform_view(self, request, *args, **kwargs):
        # stash the request
        self.set_request(request)

        # call the parent view method with all the original args
        return super(ModelAdminRequestMixin, self).changeform_view(request, *args, **kwargs)

    def add_view(self, request, *args, **kwargs):
        self.set_request(request)
        return super(ModelAdminRequestMixin, self).add_view(request, *args, **kwargs)

    def change_view(self, request, *args, **kwargs):
        self.set_request(request)
        return super(ModelAdminRequestMixin, self).change_view(request, *args, **kwargs)

    def changelist_view(self, request, *args, **kwargs):
        self.set_request(request)
        return super(ModelAdminRequestMixin, self).changelist_view(request, *args, **kwargs)

    def delete_view(self, request, *args, **kwargs):
        self.set_request(request)
        return super(ModelAdminRequestMixin, self).delete_view(request, *args, **kwargs)

    def history_view(self, request, *args, **kwargs):
        self.set_request(request)
        return super(ModelAdminRequestMixin, self).history_view(request, *args, **kwargs)


class TrackObjAdminMixin:
    def get_form(self, request, obj=None, **kwargs):
        request._obj_ = obj
        return super().get_form(request, obj, **kwargs)


class RequestFormInlineMixin:
    def get_formset(self, request, obj=None, **kwargs):
        formset = super(RequestFormInlineMixin, self).get_formset(request, obj=obj, **kwargs)
        formset.form.request = request
        return formset


class RelatedCountAdmin:
    count_fields = ()

    def get_count_fields(self, request, obj=None):
        return self.count_fields

    def get_queryset(self, request):
        qs = super(RelatedCountAdmin, self).get_queryset(request)
        qs = qs.annotate(*(Count(field) for field in self.get_count_fields(request)))
        return qs


class NameSlugModelAdmin(
    admin.ModelAdmin
):
    search_fields = ('name',)