Search code examples
djangoforeign-keyslimit-choices-to

is it possible to have two parameters in limit_choices_to in django models?


I'll shorten the code as simple as possible. Supposedly, we do have two models.

models.py > Products table

CATEGORY = (
    ('Hard Disk Drive', 'Hard Disk Drive'),
    ('Solid State Drive', 'Solid State Drive'),
    ('Graphics Card', 'Graphics Card'),
    ('Laptop', 'Laptop'),
    ('RAM', 'RAM'),
    ('Charger', 'Charger'),
    ('UPS', 'UPS'),
    ('Mouse', 'Mouse'),
    ('Keyboard', 'Keyboard'),
    ('Motherboard', 'Motherboard'),
    ('Monitor', 'Monitor'),
    ('Power Supply', 'Power Supply'),
    ('Router', 'Router'),
    ('AVR', 'AVR'),
    ('Tablet', 'Tablet'),
    ('System Unit', 'System Unit'),
    ('Audio Devices', 'Audio Devices'),
    ('CPU', 'CPU'),
    ('Others', 'Others'),
)

class Product(models.Model):
model_name = models.CharField(max_length=100, null=True, blank=True)
asset_type = models.CharField(max_length=20, choices=CATEGORY, blank=True)
date = models.DateField(null=True, blank=True)

And the other table > Order table

class Order(models.Model):
product_order = models.ForeignKey(Product, on_delete=models.CASCADE, null=False)
employee = models.ForeignKey(User, models.CASCADE, null=False)
date = models.DateTimeField(auto_now_add=True)
remarks = models.TextField()

And we all know that adding this code will limit the foreignkey choices under the Order form.

limit_choices_to={"asset_type": "Hard Disk Drive"}
limit_choices_to={"asset_type": "Solid State Drive"}

My goal here is to show items from Products table whose asset_type is either "Hard Disk Drive" OR "Solid State Drive". I've read the documentation of Django for "limit_choices_to" and can't see any pertaining to some kind of solution in here. Thank you in advance who knows a way to make this possible.


Solution

  • You can work with the __in lookup [Django-doc] to specify a list of allowed values:

    class Order(models.Model):
        product_order = models.ForeignKey(
            Product,
            on_delete=models.CASCADE,
            limit_choices_to=dict(asset_type__in=['Hard Disk Drive', 'Solid State Drive'])
        )
        # …

    Note: Specifying null=False [Django-doc] is not necessary: fields are by default not NULLable.


    Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.