Ilya
Ilya

Reputation: 99

Django: Use limit_choices_to to limit choices in Admin menu

I have a model in Django:

class Task(models.Model):  
    product = models.ForeignKey(Product)  
    content = models.OneToOneField(ContentDataSet)  

How can I use option limit_choices_to= for content field if I want to show only not yet assigned ContentDataSet options AND already assigned to this Task options in user/admin in standart drop-down choicelist?

I tried to use limit_choices_to = {'task__isnull':True}, but in that case I can't see already assigned to this Task content options.

limit_choices_to = models.Q(task__isnull=True) | models.Q(task=self) is not working because self is not defined

Upvotes: 1

Views: 5872

Answers (2)

Emilio
Emilio

Reputation: 2752

This can't be done with limit_choices_to. But you can use two different approaches that work OK:

1) For ForeignKeys you can use formfield_for_foreignkey to override the queryset in your ModelAdmin like this:

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if request.user.is_superuser:
        return super(UserOwnerProtectorModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    if db_field.name == "task":
        # This next line only shows owned objects
        # but you can write your own query!
        kwargs["queryset"] = db_field.related_model.objects.filter(user=request.user)
    return super().formfield_for_foreignkey(db_field, request, **kwargs)

2) And as a second choice here is an example that overrides the field queryset which can help you on the OneToOne field: Django ForeignKey limit_choices_to a different ForeignKey id

Good luck!

Upvotes: 2

kszl
kszl

Reputation: 1213

Limit_choices_to is a Q object. In docs you have an example of making similar restriction on ForeignKey: https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.limit_choices_to

More about queries is here: https://docs.djangoproject.com/en/dev/topics/db/queries/

Upvotes: 0

Related Questions