简体   繁体   中英

Filter ModelChoiceField by User in Django Admin Form

I'm new in Django and I have created a project with this structure:

model.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)

I want to show only the records that are assigned to a specific Group. It´s ok, but how could I create the same filter that I use in admin.py to filter the choices by user´s group in my Django form? How could I pass the actual user that is logging to a ModelForm class?

Forms.py

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

Thanks!

You can't do it in the field definition as you'll need the request object. I think the only way to do it is to define formfield_for_dbfield on the admin class:

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

Haven't tested the code, so it might be wrong :-)

With formfield_for_dbfield i have founded the answer :)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM