对this question的一些评论表明,有更直接和最新的解决方案。 (我没找到)
(评论如下:“是的,它已经解决。只需在参数中传递相关实例,它就会预先填充它......”让我觉得现在很容易,但我仍然无法使其工作)
问题是我想向一些参与特定事件并由管理员选择的用户发送通知。 工作人员在事件的页面上,选择事件并保存它,而内联中的fk字段应该预先填充所涉及的用户名。 (等待工作人员检查或取消选中接收电子邮件通知)
出于可用性的原因,至关重要的是,这应该采用内联形式,因为已经有很多页面要从员工那里收集所有必要的信息。
有什么想法吗?
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)
答案 0 :(得分:1)
我不相信内联是这样的方式。如果应该提示工作人员向参与事件的用户发送电子邮件,并且需要控制实际通知哪些用户,那么您应该使用中间视图。
首先,您需要一个表单,让您选择属于该事件的用户。最初,我们将users
字段设置为仅为所有用户,但在表单的__init__
方法中,我们将采用“事件”kwarg并根据该字段过滤字段。
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()
其次,您在ModelAdmin
上创建一个视图,其行为与普通表单视图一样:
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))
你当然需要为此创建模板,但这很简单。表单已经设置为显示一个复选框列表,每个用户一个,因此您可以获得所需的所有信息。
第三,将此观点与您的ModelAdmin
网址绑定:
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
第四,在保存后重写change_view
以重定向到此视图:
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