2012-01-31 104 views
1

this question的一些注释表明存在更直接和最新的解决方案。 (我没有找到任何)Django Admin:如何根据父模型“预填充”内联外键字段

(评论:“是的,它解决了。只需传递参数中的相关实例,它将预先填充它...”让我觉得现在很容易,但我仍然可以不要让它工作)

事情是,我想发送通知给某些用户参与特定事件,并由管理员选定。 工作人员在事件的页面上,选择事件并保存它,比inline中的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

为什么不解决它通过创建过滤所有收到(或未收到)通知的用户的用户模型?然后,您可以创建发送通知的管理操作。 – 2012-01-31 17:35:27

+0

这些步骤是:过滤与用户剧场戏有关的用户。让工作人员指出哪些人会收到关于重新发布(事件)的通知 - 并非所有人都是必要的(例如,导演没有参加所有报复)。此操作在员工提交有关此特定事件的所有其他信息时完成。 – tookanstoken 2012-02-01 01:36:34

+0

这使得它更清晰。那么为什么不通过在与用户相关的事件中有多对多来解决呢?它可以是[filter_horizo​​ntal](https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.filter_horizo​​ntal)或[内嵌](https: //docs.djangoproject.com/en/dev/ref/contrib/admin/#working-with-many-to-many-models)。然后,您可以向这些用户发送通知。 – 2012-02-01 05:26:36

回答

0

我不相信内联是去这样的事情的方式。如果应提醒员工电子邮件参与事件的用户,并需要控制实际通知哪些用户,则应使用中间视图。

首先,您需要一个可以让您选择属于​​该事件的用户的表单。最初,我们将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 
+0

谢谢,我试图获得大部分答案,但我必须将它与“何时”模型一起放在一个页面中。否则它会变得一团糟,并且会导致可用性灾难。最后,他们不会使用它。我相信这是可能的,我有我需要的所有信息,只是将它们连接在一起...如果Django方式失败,我必须使用js(即使我的js技能吸) – tookanstoken 2012-02-01 01:21:31

相关问题