# documents/admin.py from django.contrib import admin from django.utils.translation import gettext_lazy as _ from django.utils.html import format_html, mark_safe from django.urls import reverse from .models import Document, DocumentAcknowledgement from django.contrib.auth import get_user_model User = get_user_model() class AcknowledgementInline(admin.TabularInline): model = DocumentAcknowledgement extra = 0 can_delete = False verbose_name = _("Ознакомление") verbose_name_plural = _("Ознакомления") fields = ('user_link', 'acknowledged_at') readonly_fields = ('user_link', 'acknowledged_at') def user_link(self, obj): url = reverse( 'admin:{}_{}_change'.format( User._meta.app_label, User._meta.model_name ), args=[obj.user.pk] ) return format_html('{}', url, obj.user.get_full_name() or obj.user) user_link.short_description = _("Сотрудник") @admin.register(Document) class DocumentAdmin(admin.ModelAdmin): inlines = [AcknowledgementInline] list_display = ( 'title', 'uploaded_at', 'sent_to_all', # убрали 'pending_summary' ) list_filter = ('sent_to_all', 'uploaded_at') search_fields = ('title', 'description') filter_horizontal = ('recipients',) actions = ['send_document'] fieldsets = ( (None, { 'fields': ('title', 'file', 'description', 'recipients', 'sent_to_all'), }), (_('Meta'), { 'fields': ('uploaded_by', 'uploaded_at'), 'classes': ('collapse',), }), (_('Ознакомление'), { 'fields': ('recipients_summary', 'pending_list'), }), ) readonly_fields = ( 'uploaded_by', 'uploaded_at', 'recipients_summary', 'pending_list', ) def save_model(self, request, obj, form, change): if not obj.pk: obj.uploaded_by = request.user super().save_model(request, obj, form, change) def send_document(self, request, queryset): from .tasks import send_document_to_recipients for doc in queryset: send_document_to_recipients.delay(doc.id) self.message_user(request, _("Рассылка запущена.")) send_document.short_description = _('Отправить документ') def get_recipients_qs(self, obj): return User.objects.filter(is_active=True) if obj.sent_to_all else obj.recipients.all() def recipients_summary(self, obj): qs = self.get_recipients_qs(obj) names = [u.get_full_name() or str(u) for u in qs[:5]] count = qs.count() if count > 5: return format_html("{}… (ещё {})", ", ".join(names), count - 5) return ", ".join(names) if names else _("— никто —") recipients_summary.short_description = _('Получатели') def pending_list(self, obj): recipients = set(self.get_recipients_qs(obj)) acked_ids = set( DocumentAcknowledgement.objects .filter(document=obj) .values_list('user_id', flat=True) ) pending = [u for u in recipients if u.id not in acked_ids] if not pending: return format_html('{}', _("Все ознакомились")) links = [] for u in pending: url = reverse( 'admin:{}_{}_change'.format( User._meta.app_label, User._meta.model_name ), args=[u.pk] ) links.append(format_html('{}', url, u.get_full_name() or u)) return mark_safe('
'.join(links)) pending_list.short_description = _('Кто ещё не ознакомился') @admin.register(DocumentAcknowledgement) class DocumentAcknowledgementAdmin(admin.ModelAdmin): list_display = ('document', 'user', 'acknowledged_at') list_filter = ('document', 'acknowledged_at') search_fields = ('user__phone_number', 'user__last_name', 'document__title') readonly_fields = ('user', 'document', 'acknowledged_at') ordering = ('-acknowledged_at',)