Как получить foreighkey из foreighkey без цикла в django?
Это проект Django, я пытаюсь создать список желаний (many-to-many не поможет, потому что мне нужно DateTime получения желаемого элемента в списке желаний).
class Client(models.Model):
name = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField()
class WishItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
client = models.ForeignKey(Client, related_name="wishlist", on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)
Что я могу сделать, так это только следующее:
wishlist = Client.objects.wishlist.select_related('product').all()
wish_products = [item.product for item in wishlist]
Но мне нужно что-то вроде этого, без цикла, но с одним SQL запросом и одной строкой
wishlist = Client.objects.wishlist.product.all()
Когда я пытаюсь запустить этот код, я получаю ошибку AttributeError: 'RelatedManager' object has no attribute 'product'
Отношения "многие ко многим" решат проблему, вы можете добавить дополнительные поля в класс WishItem, попробуйте сделать это :
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField()
class Client(models.Model):
name = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
WishProducts = models.ManyToManyField(Product,through='WishItem')
class WishItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
client = models.ForeignKey(Client, on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)
You can .filter(…) [Django-doc] and then .order_by(…) [Django-doc] with:
Product.objects.filter(wishitem__client__user=my_user).order_by('wishitem__added_at')
Вы можете сделать его более удобным для запроса, соединив ManyToManyField с вашим WishItem:
class Client(models.Model):
# …
wishlist = models.ManyToManyField(
'Product',
through='WishItem'
)
class Product(models.Model):
# …
pass
class WishItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
client = models.ForeignKey(Client, related_name='wishitems', on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)
тогда вы можете запросить:
Product.objects.filter(client__user=my_user).order_by('wishitem__added_at')
Это также сделает запрос на .wishlist из Client более ковенантным, из Product, где .client_set является менеджером, который управляет Client, у которых есть этот Product в списке желаний.
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 theUsermodel [Django-doc] directly. For more information you can see the referencing theUsermodel section of the documentation.