1

I'm new to Django so I make 3 simple tables to return a WishList. The thing is that I want whenever user asks for WishList, his/her user_id is used to make a SELECT query to return his/her own WishList. And I want to get product title and product url from my WishList table. I'm using to_field but with that way I only can get product title back. I don't know much about Django so help me!

Product

class Product(models.Model):
    class Meta:
        unique_together = (('id', 'title'),)
    title = models.CharField(max_length=200, unique=True,
                             help_text='Name of the product')
    url = models.CharField(max_length=300, default='',
                           help_text='Url of the product')

    def __str__(self):
        return 'Product: {}'.format(self.title)

WishList

class WishList(models.Model):
    class Meta:
        unique_together = (('user', 'product'),)

    user = models.ForeignKey(fbuser,
                         on_delete=models.CASCADE,
                         help_text='Facebook user',
                         to_field='user_id')
    product = models.ForeignKey(Product, to_field='title', db_column='title',
                            on_delete=models.CASCADE)

    def __str__(self):
        return 'WishList: {}'.format(self.user)
8
  • Can you show us how are you trying to access product on wish list object? Commented Oct 19, 2016 at 7:52
  • query = cur.execute("SELECT title FROM wishlist_wishlist WHERE user_id ='"+user_id+"'") I use this query Commented Oct 19, 2016 at 7:55
  • Why are you using cursors? why not use django orm docs.djangoproject.com/en/1.10/topics/db/queries/…? Commented Oct 19, 2016 at 7:58
  • Because I'm using postgresql as my database and psycopg2 works for me to get data so Commented Oct 19, 2016 at 8:04
  • 1
    Understood. You should only use cursor when you can't get desired sql in form of ORM. For your question it's pretty easy to do in ORM. Commented Oct 19, 2016 at 8:41

1 Answer 1

1

It's not a good practice to override to_field to another field different than your model.pk unless you have a really good reason and you know what you are doing (definitely not the case right now).

So after you read the docs, you will know that in order to get wishlisht related to a user, you can use the ForeignKey reverse relation to get all related wishlists for a user.

user_wishlists = my_user.wishlist_set.all()
#Because we know that you want to access the wishlist.products
#in order to optimize things (in terms of db queries)
#you can add and .select_related('product')
#e.g, user_wishlists = my_user.wishlist_set.all().select_related('product')

#now follow the wishlist.product foreign key to access the related product for every wishlist
for wishlist in user_wishlists:
    product = wishlist.product
    print (product.id, product.title, product.url)

Now after you read a little bit more of the documentation you will notice that your WishList model is in fact an intermediate model for a ManyToMany relation between User and his wished products, then you will know that you can define a M2M field between user and products via WishList like so:

class FbUser(models.Model):
    #...
    wished_products = models.ManyToManyField(
        Product,
        through='WishList',
        through_fields=('user', 'product')
    )

#and now accessing user wished products would be easy as:
user_wished_products = my_user.wished_products.all()
for product in user_wished_products:
    print (product.id, product.title, product.url)
Sign up to request clarification or add additional context in comments.

4 Comments

AttributeError: 'unicode' object has no attribute '_meta' I got this error, it causes because first parameter to ManyToManyField must be either a model, a model name or string. It's weird because Product is a model
I guess the Product class is defined in another application? Try to refer it with the application name too, e.g. 'myapp.Product'.
Yes, all 3 tables are all made in different application. I tried to use 'myapp.Product' but it doesn't work for me. What I did is just add a column url in my WishList model, then return it with the title also. It worked but I dont think that it's good code. So i'm still trying to better my code
Instead of writing it as a string 'myapp.Product', try to import the class (e.g. from myapp.models import Product), then send that to the M2M field definition: models.ManyToManyField(Product, ....) (no string used).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.