Django限制ManytoMany基于选定的FK的查询集

sup*_*er9 11 django django-admin

我有一个看起来像这样的模型:

class Invite(models.Model):
    user = models.ForeignKey(User)
    event = models.ForeignKey(Event)
    roles = models.ManyToManyField(Role, blank=True, null=True)
    sent =  models.BooleanField("Invite Sent", default=False, editable=False)
    created = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return u"%s" % self.user

    class Meta:
        unique_together =(('user','event'),)


class Role(models.Model):
    """
    This associates a user's role to an event
    """
    event = models.ForeignKey(Event, related_name="roles")
    roletype = models.ForeignKey(RoleType)
    profiles = models.ManyToManyField(Profile, related_name="roles",
            blank=True, null=True)
    modified = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)
Run Code Online (Sandbox Code Playgroud)

因此,无论何时创建新事件,都会创建一堆角色.在Invite模型中,我如何只显示与我在Django Admin中的更改表单中选择的事件相关联的角色,而不是显示Role模型中的所有条目?

DrM*_*ers 10

你可能想要一些东西:

class InviteAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        self.instance = obj # Capture instance before the form gets generated   
        return super(InviteAdmin, self).get_form(request, obj=obj, **kwargs)

    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        if db_field.name == 'role' and self.instance:
            # restrict role queryset to those related to this instance:         
            kwargs['queryset'] = self.instance.event.roles.all()
        return super(InviteAdmin, self).formfield_for_manytomany(
            db_field, request=request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

Django文档 formfield_for_manytomany

  • 问题清楚地说明了"我怎样才能在**变更形式**中显示与我选择的事件相关的角色**"这绝对是动态的(ajax).您的解决方案是静态的 (2认同)

Pan*_*nnu 6

您想要动态过滤选项roles choices,因此您需要ajax执行此任务.

这是你如何使这项工作..

1: OnChange在中event发送的event_id,以自定义的view通过ajax.

2:从基于您从请求中获得的Roles模型并将过滤后的内容返回到.filterevent_idajaxrolesserializingJSON

3:roles通过解析JSON响应来清除现有和重新填充.

例如:这个jquery getJSON例子

JavaScript的:

$("#event").change(function (){         
 var event_id = $(this).val();              
    $.getJSON("/my-app/my-roles-filter-view/"+ event_id +"/",function(data){
        var roles_dd = $("#roles");
        $('#event >option').remove();
        $.each(data, function(index,value) {
        roles_dd.append($("<option />").val(value).text(value));
    });                 
})(django.jquery);
Run Code Online (Sandbox Code Playgroud)

网址:

('^/my-app/my-roles-filter-view/(?P<event_id>\d+)/$','my_view'),
Run Code Online (Sandbox Code Playgroud)

观点:

def my_view(request,event_id):
    qs = Role.objects.filter(event=event_id).values_list('id')
    return HttpResponse(simplejson.dumps(qs),mimetype='application/javascript')
Run Code Online (Sandbox Code Playgroud)

这只是一个使用jquery你的例子可以使用任何类型ajax并实现这一点.

  • 不,这可以(并且应该)在Python代码中实现. (4认同)