It is a Django project, I am trying to create a wishlist (many-to-many will not help because I need DateTime of getting that wished item in the wishlist).
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)
What I could do is only this:
wishlist = Client.objects.wishlist.select_related('product').all()
wish_products = [item.product for item in wishlist]
But I need something like this, without a loop but with a single SQL query and single line
wishlist = Client.objects.wishlist.product.all()
When I try to run this code I get an error AttributeError: 'RelatedManager' object has no attribute 'product'
CodePudding user response:
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')
You can make it more covenient to query by spanning a ManyToManyField
with your 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)
then you can query with:
Product.objects.filter(client__user=my_user).order_by('wishitem__added_at')
It will also make querying for the .wishlist
of the Client
more covenient, of the Product
s where the .client_set
is a manager that manages the Client
s that have that Product
on the wishlist.
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 theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
CodePudding user response:
Many to many relationship will fix the problem you can add extra fields to your WishItem class you can try this :
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)