首页 > 解决方案 > Django ORM: Many to Many Self-Reference with Through Model

问题描述

I have a many-to-many self-referencing relationship that includes a through model. Products are composed of other Products, including an amount (I.E a screw is made from iron rods). I made the through model, although I can't seem to access the 'amount' field in the through model:

Model code:

from django.db import models


class Product(models.Model):
    name = models.CharField(max_length=200, unique=True)
    produced = models.IntegerField(default=0)
    speed = models.IntegerField()
    type = models.CharField(max_length=200)
    ingredients = models.ManyToManyField('self', through='RecipeComponent', symmetrical=False)

    def __str__(self):
        return self.name


class RecipeComponent(models.Model):
    item = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="item")
    ingredient = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="ingredient")
    amount = models.IntegerField()

    def __str__(self):
        return str(self.amount) + " of " + self.ingredient.name

I've tried a number of other queries, but as you can see they seem to fail. I know I'm missing something but I can't put my finger on it.

screw.ingredients.all()
>>> <QuerySet [<Product: iron_rod>]>
screw.ingredients.all()[0].amount
>>> Traceback (most recent call last):
>>>     File "<input>", line 1, in <module>
>>>     AttributeError: 'Product' object has no attribute 'amount'

标签: djangodjango-modelsorm

解决方案


您可以在 Product 类中创建一个返回给定成分数量的方法:

class Product(models.Model):
    ...
    ...
    def get_amount_of_ingredient(self, ingredient):
        try:
            return RecipeComponent.objects.get(item=self, ingredient=ingredient).amount
        except RecipeComponent.DoesNotExist:
            return 0

然后从screw对象调用它:

screw.get_amount_of_ingredient("iron_rod")

推荐阅读