How to fill value in a limit_choices_to option in OneToOneField for Django Admin?

362 Views Asked by At

I need to limit the choices in a Django Admin form but cannot come up with a solution. Given these models:

class ProductFamily(models.Model):
    name = models.CharField(max_length=250)
    default_product_to_display = models.OneToOneField('Product', limit_choices_to={'product_family': ??????}) 
    # Enclosing Product reference in quotes is necessary since the Product declaration is below ProductFamily declaration

class Product(models.Model):
    name = models.CharField(max_length=250)
    image = models.ImageField(upload_to='images/',blank=True,null=True)
    product_family = models.ForeignKey(ProductFamily)

What should be placed in the ??????'s in class ProductFamily? I've tried everything I can think of including name, 'name' ProductFamily, 'Product Family', self, self.id. The options with self return an Internal Server Error. The quoted options return: 'invalid literal for int()'. When "name" is used unquoted, it returns: int() argument must be a string or a number, not 'CharField'.
If I put a hard-coded integer value in to test it, then it works fine, so it is obviously looking for an integer value. I also tried, without success, placing both id = models.AutoField(primary_key=True) in the declaration with id at the ??????'s as well as defining a function that returns self.id, but none of this works.

So - how do I limit the selection of products by showing only those whose product_family id's match those of the current ProductFamily?

1

There are 1 best solutions below

2
On

The best way to do this is to use a custom form to limit the queryset of the field, as trying to set limit_choices_to dynamically is super tough, if not completely impractical.

Example:

class ProductFamilyForm(forms.ModelForm):

    def __init__(self *args, **kwargs):
        if 'initial' in kwargs:
            self.fields['default_product_to_display'].queryset = Product.objects.filter(
                product_family=initial.product_family)