简体   繁体   中英

django filter by nested foreign key

Souupose I have two models like below:

class ProductType(models.Model):
    name = models.CharField(max_length=50)
    parent = models.ForeignKey('self', related_name='children', bland=True, null=True)


class Product(models.Model):
    name = models.CharField(max_length=50)
    product_type = models.ForeignKey(ProductType)

Now I have ProductType hierarchy like this:

Electronics->MobilePhone->Samsung->[galaxy, s10, s8]
Electronics->MobilePhone->Apple->[Iphone, Ipad, Ipod]

For sure, MobilePhone is under Electronics and Apple is under MobilePhone ProductType and finally [galaxy, s10, s8] are Products of Samsung ProductType. Now how can I filter on Product model to get all the Products where ProductType=MobilePhone ?

如果您使用的是 Django 2,您应该添加 on_delete (models.CASCADE, models.PROTECTED, models.SET_NULL) 我通常做的只是让它尽可能无错误的是:

prods = Product.objects.filter(product_type__name__iexact="MobilePhone")

Maybe you need to write a raw query to get the last limit of the chain. If it's an infinity chain, then you will need to check the next result using a loop. I just hope you will get a better answer from better developers and I will be able to learn it too.

You can add a property to your Product model that returns a list of all the ProductType objects that it is a part of . Like so:

class Product(model.Model):
    name = ...
    product_type = ...

    @property
    def product_types_list(self):
        product_types = []
        obj = self  # reference object
        while obj.product_type is not None:
            product_types.append(obj.product_type)
            obj = obj.product_type
        # Reverse the list to get the proper hierarchy
        product_types.reverse()
        return product_types

After that, you can filter the products like so:

mobile_phone_type = ProductType.objects.get(name='MobilePhone')

mobile_phones = []  # list of filtered mobile phones

for product in Product.objects.all():
    if mobile_phone_type in product.product_types_list:
        mobile_phones.append(product)

Your required items will then be stored in the mobile_phones list.

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