I am working on an application where currently, I have
1) Staff Model is connected to User model via OneToOne Relationship and can have more than one Group.
2) Meeting model can also assigned to many Group.
3) RSVPinline is a part with MeetingAdmin as a inline form.
Here i was trying to automatically ADD all 'Staff' associated in Selected Groups in django admin form while creating Meetings.
I have tried save_model to add current user in meeting's 'creator' field.
models.py
class Group(models.Model):
name = models.CharField(max_length=200)
class Staff(models.Model):
fullname = models.CharField(max_length = 250,verbose_name = "First Name")
group = models.ManyToManyField(Group, blank=False,verbose_name = "Meeting Group") # protect error left to add
is_active = models.BooleanField(default=True)
user = models.OneToOneField(User, on_delete=models.CASCADE,null=True, blank=True,verbose_name = "Associated as User") # protect error left to add
left_date = models.DateField(null=True, blank=True,verbose_name = "Resigned Date")
class Meeting(models.Model):
title = models.CharField(_('Title'), blank=True, max_length=200)
start = models.DateTimeField(_('Start'))
group = models.ManyToManyField(Group, blank=False,verbose_name = "Meeting Group") # protect error left to add
location = models.ForeignKey(Location, blank=False,verbose_name = "Location",on_delete=models.CASCADE) # protect error left to add
class RSVP(models.Model):
meeting = models.ForeignKey(Meeting, on_delete=models.CASCADE)
responder = models.ForeignKey(User, editable=True, on_delete=models.CASCADE, null=True, blank=True,verbose_name = "Attendees", related_name='guest')
response = models.CharField(max_length = 20, choices= MEETING_RSVP, default='No response', verbose_name = "Status",null=True, blank=True)
admin.py
class RSVPInline(admin.TabularInline):
model = RSVP
extra = 0
class MeetingAdmin(admin.ModelAdmin):
form = MeetingForm
list_display = ('title', 'location', 'start','creator' )
inlines = [RSVPInline, TaskInline]
#Currently using save_model to automatically add current user as a creator
def save_model(self, request, obj, form, change):
obj.creator = request.user
super().save_model(request, obj, form, change)
My pseudo code is:
grouplist = Get group's list from submitted MeetingForm
stafflist = Staff.objects.filter(department__in =grouplist).values_list('id', flat=True).distinct()
Add to RSVPInline:
values = list(for staff in stafflist:
'responder' = staff
'meeting' = 'meeting from MeetingForm'
'response' = has a default value in model
bulk_create() RSVPInline with values
You can extend save_related() ModelAdmin method to perform additional actions after form object (Meeting) and its Inlines (RSVPs, if present in submitted form) are saved:
class MeetingAdmin(admin.ModelAdmin):
...
def save_related(self, request, form, formsets, change):
# call original method - saves Meeting and inlines
super(MeetingAdmin, self).save_related(request, form, formsets, change)
# get this form Meeting
obj = form.instance
# get Staff members of this meeting groups
# and we can exclude ones already having
# RSVP for this meeting
stafflist = Staff.objects.filter(
group__in=obj.group.all()
).exclude(
user__guest__meeting=obj
)
rsvps = list(
RSVP(responder=staff.user, meeting=obj)
for staff in stafflist
)
# calls bulk_create() under the hood
obj.rsvp_set.add(*rsvps, bulk=False)
** Few possibly useful notes:
group
field may be better to be called groups
as it represents ManyToMany relation and returns multiple objectsrelated_name
represents relation from the related object back to this one so it may be more logical to use something like invites
instead of guest