Django: limiting querysets in admin forms
Let’s suppose you have two related types of objects in your Django app. Call them Object and SuperObject, related ManyToMany‘ly. And when you add/change SuperObject in Django admin, there’s all Objects available for selection. But you need to limit the choices, and limit dynamically (perhaps, depending on current user). Here’s quite straightforward but working technique.
def make_metaform(user): class MetaForm(forms.ModelForm): class Meta: model = SuperObject objects_list = forms.ModelMultipleChoiceField( queryset=Object.objects.filter(objectmod__user__id=user.id, objectmod__can_read=True)) return MetaForm class MetaAdmin(ZpixObject): def __call__(self, request, url): self.form = make_metaform(request.user) return ZpixObject.__call__(self, request, url)
What do we do here:
function make_metaform takes User object and returns forms.Form subclass (class factory)
this function creates common forms.ModelForm for SuperObject
then it overrides standard (for ManyToMany relationship) objects_list attribute with the same forms.ModelMultipleChoiceField, but having other queryset parameter
in our example we filter Objects by permissions, stored in other table/model — ObjectMod
we should use modified subclass ModelAdmin for managing SuperObjects in admin
as new MetaAdmin is created (__call__ed), we call metaform function and assign its result to standard ModelAdmin attribute form
then we call standard ModelAdmin class method
Comments
Comments powered by Disqus