0

I am trying to write a scheduling app. Here there are multiple workers and I create a group of workers. The Group is used as a template to create schedule.

When I create a Schedule object I want to take input of a Group object and copy the members from the Group object to the Schedule object. I don't want to give a ForeignKey to the Group object itself because the workers might change for a single day, whereas the group should be left intact as a template.

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)

I understand this can be done easily with views and html templates. But I am trying to do the same under admin page. I have a form for Schedule and registered it in 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

I don't quite understand how to receive this input and process the Group object instance and copy the members. Any help is much appreciated.

Thanks in advance.

bharath
  • 5
  • 3

1 Answers1

1

I think there are a number of ways to approach this. One approach could be overriding the save_model method in your 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)

Please be aware that this is only a very quick and dirty example, adding the members from the selected group each time you save the object. If you modify an existing schedule the obj arg in the method gives you that instance and the change arg would be True. You might want to implement some additional checks and remove existing members before you add the members of the group in cases where you modify an existing schedule.

More details on the admin site, exisiting methods and what you can do can be found in the django docs.

Chris
  • 2,162
  • 1
  • 6
  • 17
  • Thanks for the suggestion. That worked – bharath Jan 04 '22 at 18:52
  • A followup question. I am trying to change the "add" or insert view and keep the "change" or edit view intact. I know we can do this by creating a `add_form_template` and extending the admin/change_form.html in the template. Is this the best way of doing it or is there any other "quick and dirty" easier way of doing this? Thanks in advance – bharath Jan 04 '22 at 20:34
  • This answer is exactly what I wanted :) Never mind the question. https://stackoverflow.com/questions/44877651/django-model-admin-add-form-gets-stuck – bharath Jan 04 '22 at 20:43