Копирование объектов в Django Admin
Дублирование мероприятий в Django Admin
В этом посте мы разберем код, который позволяет дублировать мероприятия в Django Admin. Код представляет собой действие администратора, которое можно применить к нескольким мероприятиям одновременно.
Код
def duplicate_model(modeladmin, request, queryset):
"""
Дублирует мероприятия и связанные модели.
"""
if queryset:
obj_id = queryset.first().pk
for model in queryset:
model.pk = None
model.save()
_duplicate_related_models(model, obj_id)
modeladmin.message_user(request, f"Дублирование прошло успешно, id - {model.pk}")
else:
modeladmin.message_user(request, "Нет мероприятий для дублирования")
def _duplicate_related_models(model, obj_id):
"""
Копирует связанные модели для мероприятия.
"""
related_models = [
EventAdvantageInlineAdmin.model,
EventHallImageInlineAdmin.model,
EventWelcomeSpeechInlineAdmin.model,
AdBlockEventInlineAdmin.model,
SponsorEventInlineAdmin.model,
SpecializationEventInlineAdmin.model,
ProgramEventInlineAdmin.model,
SponsorEventVideoInlineAdmin.model,
EventPartnerInlineAdmin.model,
EventOrganizerInlineAdmin.model,
EventContactInlineAdmin.model,
]
for inline in model._meta.get_fields():
if isinstance(inline, ManyToOneRel) and issubclass(inline.related_model, tuple(related_models)):
for related in inline.related_model.objects.filter(event_id=obj_id):
related.pk = None
related.event = model
related.save()
duplicate_model.short_description = "Дублировать выбранное мероприятие"
@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
"""Мероприятия"""
actions = [duplicate_model]
list_display = ["id", "name", "date_event"]
list_display_links = ("name",)
save_on_top = True
inlines = [
EventAdvantageInlineAdmin,
EventHallImageInlineAdmin,
EventWelcomeSpeechInlineAdmin,
AdBlockEventInlineAdmin,
SponsorEventInlineAdmin,
SpecializationEventInlineAdmin,
ProgramEventInlineAdmin,
SponsorEventVideoInlineAdmin,
EventPartnerInlineAdmin,
EventOrganizerInlineAdmin,
EventContactInlineAdmin,
]
Обзор
Код состоит из двух частей: действия администратора duplicate_model
и регистрации этого действия для модели Event
.
Действие администратора
Действие администратора duplicate_model
принимает три аргумента: modeladmin
, request
и queryset
. modeladmin
- это экземпляр класса ModelAdmin
, request
- это запрос, который вызвал действие, а queryset
- это набор объектов, к которым применено действие.
Действие делает следующее:
- Извлекает идентификатор первого объекта в наборе (
obj_id
). - Проходит по каждому объекту в наборе и:
- Устанавливает идентификатор объекта в
None
, чтобы создать новую копию. - Сохраняет объект.
- Копирует связанные модели (см. ниже).
- Устанавливает идентификатор объекта в
- Отображает сообщение об успешном дублировании.
Копирование связанных моделей
Код копирует связанные модели, которые имеют отношение к мероприятию. Это делается с помощью цикла по полям модели (model._meta.get_fields()
). Если поле является отношением к другой модели (ManyToOneRel
), код проверяет, является ли эта модель одной из перечисленных в условии (if issubclass(inline.related_model, ...)
). Если да, то код копирует связанные объекты, устанавливая их идентификатор в None
и сохраняя их.
Регистрация действия
Действие регистрируется для модели Event
с помощью декоратора @admin.register(Event)
. Это позволяет применять действие к нескольким мероприятиям одновременно в интерфейсе администратора.
Результат
Выводы
Код позволяет дублировать мероприятия в Django Admin, копируя связанные модели. Это может быть полезно для создания копий мероприятий с сохранением связей между ними.