【问题标题】:Filter ModelChoiceField by User in Django Admin Form在 Django 管理表单中按用户过滤 ModelChoiceField
【发布时间】:2014-09-22 10:40:13
【问题描述】:

我是 Django 新手,我创建了一个具有这种结构的项目:

模型.py

from django.contrib.auth.models import User, Group

class MyModel(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(User, null=True, blank=True)
    group = models.ForeignKey(Group, null=True, blank=True)
    ...
    ...

admin.py

class MyModelAdmin(admin.ModelAdmin):
    form = MyModelForm
    ...

    def queryset(self, request):
        qs = super(MyModelAdmin, self).queryset(request)
        # If super-user, show all records
        if request.user.is_superuser:
            return qs
        # If user have group, show all records of the group
        if request.user.groups.all().count() > 0:
            return qs.filter(group=(request.user.groups.all()))
        #Show only the records that the user have been created
        return qs.filter(created_by=request.user)

我只想显示分配给特定组的记录。没关系,但是我如何创建与admin.py 中使用的过滤器相同的过滤器来过滤用户组在我的 Django 表单中的选择?如何将正在登录的实际用户传递到 ModelForm 类?

Forms.py

class MyModelForm(forms.ModelForm):
    group = forms.ModelChoiceField(Group.objects.filter(id=####),
                label=ugettext_lazy("Groups"), required=True)

谢谢!

【问题讨论】:

    标签: python django django-forms django-admin


    【解决方案1】:

    您不能在字段定义中执行此操作,因为您需要请求对象。我认为唯一的方法是在管理类上定义formfield_for_dbfield

    def formfield_for_dbfield(self, db_field, request, **kwargs):
        field = super(MyModelAdmin, self).formfield_for_dbfield(db_field, request, **kwargs)
        if db_field.name == 'groups':
            field.queryset = field.queryset.filter(user=request.user)
        return field
    

    没有测试代码,所以可能是错误的:-)

    【讨论】:

    • 感谢 Jaap3! +1,使用 formfield_for_dbfield 我已经找到了答案:)
    【解决方案2】:

    有了formfield_for_dbfield,我找到了答案:)

    admin.py

    class MyModelAdmin(admin.ModelAdmin):
        form = MyModelForm
        ...
        def get_form(self, request, obj=None, **kwargs):
            kwargs['formfield_callback'] = partial(self.formfield_for_dbfield, request=request)
            return super(MyModelAdmin, self).get_form(request, obj, **kwargs)
    
        def formfield_for_dbfield(self, db_field, **kwargs):
            field = super(MyModelAdmin, self).formfield_for_dbfield(db_field, **kwargs)
            if db_field.name == 'group':
                field.queryset = field.queryset.filter(id__in=(kwargs['request'].user.groups.all()))
            return field
    

    【讨论】:

      猜你喜欢
      • 2014-01-31
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-23
      • 1970-01-01
      相关资源
      最近更新 更多