Khoa Nguyen
Khoa Nguyen

Reputation: 91

Using multiple columns as ForeignKey to return in another table

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)

Upvotes: 1

Views: 2854

Answers (1)

Todor
Todor

Reputation: 16050

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)

Upvotes: 1

Related Questions