Страница администратора Django копирует связанное поле ManyToMany из одной модели в другую

Я пытаюсь написать приложение для составления расписания. Здесь есть несколько workers и я создаю group группу работников. Группа используется как шаблон для создания расписания.

Когда я создаю объект Schedule, я хочу взять входные данные объекта Group и скопировать members из объекта Group в объект Schedule. Я не хочу давать ForeignKey самому объекту Group, потому что работники могут меняться в течение одного дня, в то время как группа должна оставаться нетронутой как шаблон.

models.py

class Worker(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()

class Group(models.Model):
    name = models.CharField(max_length=30)
    members = models.ManyToManyField(Worker, blank=True)

class Schedule(models.Model):
    start_time = models.DateTimeField()
    end_time = models.DateTimeField()
    date = models.DateField()
    members = models.ManyToManyField(Worker, blank=True)

Я понимаю, что это можно легко сделать с помощью views и html-шаблонов. Но я пытаюсь сделать то же самое на странице admin. У меня есть форма для Schedule и я зарегистрировал ее в admin.py

forms.py

class CreateScheduleForm(forms.ModelForm):
    group = ModelChoiceField(queryset=Group.objects.all())

    class Meta:
        model = Schedule
        fields = ( 'date', 'start_time', 'end_time')

admin.py

@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
    form = CreateScheduleForm

Я не совсем понимаю, как получить этот вход, обработать экземпляр объекта Group и скопировать members. Любая помощь будет очень признательна.

Заранее спасибо.

Я думаю, что есть несколько способов подойти к этому. Одним из подходов может быть переопределение метода save_model в вашем ScheduleAdmin:

@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
    form = CreateScheduleForm

    def save_model(self, request, obj, form, change):
        
        sched = form.save()
        group = form.data.get('group')
        for worker in Group.objects.get(pk=group).members.all():
            sched.members.add(worker)

Обратите внимание, что это всего лишь очень быстрый и грязный пример, добавляющий членов из выбранной группы каждый раз, когда вы сохраняете объект. Если вы изменяете существующее расписание, аргумент obj в методе дает вам этот экземпляр, а аргумент change будет True. Возможно, вы захотите реализовать некоторые дополнительные проверки и удалить существующие члены группы перед добавлением членов группы в случаях, когда вы изменяете существующее расписание.

Более подробную информацию об админке, существующих методах и о том, что вы можете сделать, можно найти в django docs.

Вернуться на верх