Some comments on this question indicate there is more straightforward and up-to-date solution. (I didn't find any)
(comments like: "Yes it's solved. Just pass the related instance in parameter, and it will prepopulate it..." makes me think it is easy now, but still I can't make it work)
The thing is that I want to send notice to some users which are involved in given event and selected by admin staff. Staff-member is on the page of event, selects the event and saves it, than fk fields in inline should prepopulate with involved usernames. (and waiting to staff-member to check them or uncheck them to receive e-mail notice)
For usability reasons it's critical that this should take form of inline since there are allready lot of pages to go through to gather all necessary informations from staff.
Any ideas?
class When(models.Model):
...
Date = models.DateTimeField(unique=True)
Nameofevent = models.ForeignKey(Event, to_field='Name') #the Event model gets then username from models.ManyToManyField(User, through='Role')
...
def getteam(self):
teamlist = self.Nameofevent.Roleinevent.all() # gathering users which are involved
return teamlist
getteamresult = property(getteam)
class Notice(models.Model): #this will go to the inline
...
Who = models.ForeignKey(User, blank=True)
To_notice_or_not_to_notice = models.BooleanField(default=False)
...
class NoticeInline(admin.TabularInline):
model = Notice
extra = 9
class WhenAdmin(admin.ModelAdmin):
list_display = ('Date', ...)
readonly_fields = ('getteamresult', ) #this is to make clear i have access to what i want and i can display it. prints out as [<User: someone>, <User: someoneelse>]
inlines = [NoticeInline] #but i want the User objects to prepopulate foreign field here in inline model
admin.site.register(When,WhenAdmin)
I don't believe inlines are the the way to go for something like this. If the staff-member should be prompted to email users involved in the event, and needs control over which ones are actually notified, then you should use an intermediate view.
First, you need a form that will let you select users that belong to the event. Initially, we set the users field to just be all users, but in the form's __init__ method we'll take the "event" kwarg and filter the field based on that.
class UserNotifyForm(forms.Form):
users = forms.ModelMultipleChoiceField(queryset=User.objects.all(), widget=forms.CheckboxSelectMultiple())
def __init__(self, *args, **kwargs):
event = kwargs.pop('event')
super(UserNotifyForm, self).__init__(*args, **kwargs)
if event:
self.fields['users'].queryset = event.users.all()
Second, you create a view on your ModelAdmin, that will behave just as a normal form view would:
def notify_users_view(self, request, object_id):
event = get_object_or_404(Event, id=object_id)
if len(request.POST):
form = UserNotifyForm(request.POST, event=event)
if form.is_valid():
users = form.cleaned_data.get('users')
# send email
return HttpResponseRedirect(reverse('admin:yourapp_event_changelist'))
else:
form = UserNotifyForm(event=event)
return render_to_response('path/to/form/template.html', {
'event': event,
'form': form,
}, context_instance=RequestContext(request))
You'll of course need to create template for this, but that's simple enough. The form is already set up to show a list of checkboxes, one for each user, so you have all the info you need there.
Third, tie this view into your ModelAdmin's urls:
def get_urls(self):
urls = super(MyModelAdmin, self).get_urls()
info = (self.model._meta.app_label, self.model._meta.module_name)
my_urls = patterns('',
(r'^(?P<object_id>\d+)/notify/$', self.notify_users_view, name='%s_%s_notify' % info)
)
return my_urls + urls
Fourth, override the change_view to redirect to this view after save:
def change_view(self, request, object_id, extra_context=None):
response = super(MyModelAdmin, self).change_view(request, object_id, extra_context=extra_context)
if len(request.POST):
info = (self.model._meta.app_label, self.model._meta.module_name)
response['Location'] = reverse('admin:%s_%s_notify', args=(object_id,))
# Note: this will effectively negate the 'Save and Continue' and
# 'Save and Add Another' buttons. You can conditionally check
# for these based on the keys they add to request.POST and branch
# accordingly to some other behavior you desire.
return response
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With