Connect two Django models - python

I'm trying to make a auctions website for a project and I can't get to connect 2 models, I have in my models.py file, a model for the auction listings (Alisting) and a model for the bids that are made (Bid).
-The Alisting model has 4 fields: title CharField for the title of the auction, sta_bid for a starting bid, las_bid ForeignKey to Bid model, and user ForeignKey to User model.
-The Bid model has 3 fields: user ForeignKey to User for the user that makes the bid, listing a ForeignKey to Alisting, and new_bid IntegerField for the latest bid.
class User(AbstractUser):
pass
class Alisting(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=32)
sta_bid = models.IntegerField()
las_bid = models.ForeignKey(Bid, on_delete=models.CASCADE)
class Bid(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
listing = models.ForeignKey(Alisting, on_delete=models.CASCADE)
new_bid = models.IntegerField()
How could I connect these 2 models so that when I create a listing I can create new bids to this listing from the other model. Because later in the project I'll have to allow users to modify bids from other user's listings.
Thank you in advance!

I suggest you this design:
class User(AbstractUser):
pass
class Alisting(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=32)
sta_bid = models.IntegerField()
#property
def last_bid(self):
# You don' t need to update last_bid, since is obtained dynamically with this property
if self.bid_set.objects.count() > 0:
return self.bid_set.order('-creation_date')[0]
return None
class Bid(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
listing = models.ForeignKey(Alisting, on_delete=models.CASCADE)
new_bid = models.IntegerField()
creation_date = models.DateTimeField(auto_now_add=True) # Stores the date when the bid was created
You can access the last bid with:
listing = Alisting.objects.all()[0]
print(listing.last_bid)
You can access the bids of a listing with:
listing = Alisting.objects.all()[0]
listings.bid_set.objects.all()
# Or to get only bids of a given user
listings.bid_set.objects.filter(user=User.objects.all()[0])
You can access bids of an user with:
user = User.objects.all()[0]
user.bid_set.objects.all()
# Or to get only bids of an user with a given listing
user.bid_set.objects.filter(listing=Alisting.objects.all()[0])
You can access listings created by a given user with:
user = User.objects.all()[0]
user.alisting_set.objects.all()

Related

Add product to cart using python in Django

I want to make a simple function that collects the product ID and adds it to the user's shopping cart by clicking the "add to cart" button. I have the shopping cart table and product table created but am struggling to find the correct function to add the product to the cart. Anything helps I am very new to Python and Django and am looking for some help to get me on the right track.
class Cart(models.Model):
cart_id = models.Charfield(primary_key=True)
total = models.DecimalField(max_digits=9,decimal_places=2)
quantity = models.IntegerField()
products = models.ManyToManyField(Product)
class Product(models.Model):
prod_id = models.CharField(max_length=15, null=True)
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=10,decimal_places=2)
description = models.TextField(max_length=1000)
def cart_add(request, prod_id):
item = Product.objects.get(pk=prod_id)
I know this isn't much to work with but anything helps, I am just looking for some help with creating the add to cart function
You need to have a relation between Cart model and User model, So that you can save product to respective user's cart.
Moreover a good approach would be adding another model named CartItem and keeping the product information in that model instead of storing product directly to Cart model. This is because when we add a product to cart, we might need to save and later update extra information about the product for example 'quantity'.
class Cart(models.Model):
cart_id = models.Charfield(primary_key=True)
total = models.DecimalField(max_digits=9,decimal_places=2)
quantity = models.IntegerField()
user = models.OneToOneField(User)
class CartItem(models.Model):
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
product_quantity = models.IntegerField(default=0)
user = models.OneToOneField(User)
So in this case, all you need to do is create a new CartItem object in add to cart view.:
def cart_add(request, prod_id, qty):
item = Product.objects.get(pk=prod_id)
cart_obj = Cart.objects.get(user=request.user)
CartItem.objects.create(cart=cart_obj, product=item, product_quantity=qty)
Hope this helps :)
You need a relation between Cart* and User
class Cart(models.Model):
cart_id = models.Charfield(primary_key=True)
total = models.DecimalField(max_digits=9,decimal_places=2)
quantity = models.IntegerField()
products = models.ManyToManyField(Product)
user = models.OneToOneField(User)
class Product(models.Model):
prod_id = models.CharField(max_length=15, null=True)
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=10,decimal_places=2)
description = models.TextField(max_length=1000)
def cart_add(request, prod_id):
item = Product.objects.get(pk=prod_id)
request.user.cart.add(item)

How to get the most liked users on a particular date in django

So I have a social media app, where users can like the posts of other users. Now I fetch the top 20 users who have received the most number of likes. Everything is perfect. But the problem is I cant figure out , how I can fetch the top users who have received the most likes on a particular date, for example get the top users who received most likes only today
My LIKES MODEL
class PostLike(models.Model):
user_who_liked = models.ForeignKey(User, on_delete=models.CASCADE)
post_liked = models.ForeignKey(Post, on_delete=models.CASCADE)
liked_on = models.DateTimeField(default=timezone.now)
SIMPLIFIED POST MODEL
class Post(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE,related_name='author')
caption = models.TextField()
date = models.DateTimeField(default=timezone.now)
likes = models.ManyToManyField(
User, blank=True, through=PostLike)
image = models.TextField()
class Meta:
ordering = ['-id']
SIMPLIFIED USER MODEL
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
user_name = models.CharField(max_length=100, unique=True)
date = models.DateTimeField(default=timezone.now)
profile_picture = models.TextField(
default="https://www.kindpng.com/picc/m/24-248253_user-profile-default-image-png-clipart-png-download.png")
bio = models.CharField(max_length=200, default="")
objects = CustomManger()
def __str__(self):
return self.user_name
** My query to get the top users who received the most number of likes **
users = User.objects.annotate(num__liked=Count('author__likes')).order_by('-num__likes')[:20]
# So everything is perfect and I am getting the users, now I dont know how to get the top users with most likes on a PARTICULAR DATE, for example today
** My try to get the top users with most likes on a particular day**
from django.db.models import Count, Q
from django.utils.timezone import datetime
users = User.objects.annotate(num__liked=Count('author__likes',filter=Q(author__likes__liked_on = datetime.today()))).order_by('-num__likes')[:20]
But with the above query , I cant achieve it. I am getting the error:
Related Field got invalid lookup: liked_on
I am pretty sure, I am doing something wrong with the many-many fields.
Q(author__likes__liked_on = datetime.today()) won't work, because liked_on is a datetime, while datetime.today() is a date. And the filtered field is on the 'through' table.
So you need to cast liked_on to a date, and look up the field on postlike (lower-cased by default):
Q(author__postlike__liked_on__date = datetime.today()))

Add username or any user authentication related field like first name, last name etc in model forms

I am creating a project in django in which I have two diff users i.e. Customers and restaurants.
I am creating a model for Menu in which I want add to add restaurant name in models directly(user name in this case) instead of taking input thorough forms every time.Also if possible if can take name from another field like this which is part of login system?
Models.py
class menu_details(models.Model):
restaurant_name = models.CharField(blank=True, max_length=20)
dish_name = models.CharField(blank=True, max_length=20)
dish_type = models.CharField(max_length=10, choices=food_type, default='veg')
price = models.CharField(blank=True, max_length=20)
description = models.TextField(blank=True, max_length=5000)
image = models.ImageField0(blank=True)
class Meta:
db_table = "menu_details"
If I understand well what you want, I think you need a Foreign Key Field pointing to the User infromation.
field_name= models.ForeignKey(User, help_text="", blank=True, null=True, on_delete=models.CASCADE)
Then you can access all the data from a user instance in views, for example:
this_menu = menu_details.objects.get(pk=1)
restaurant_name = this_menu.field_name.first_name
restaurant_email = this_menu.field_name.email
Or in templates:
{{ this_menu.field_name.first_name }}
{{ this_menu.field_name.email}}

sum amount field in model using another model in django

I have three models: User, Campaign and Donation. The donation model has a donation amount, donated by each user against each campaign.
Campaign model
class Campaign(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
# this is many to one relationship, on_deleting user, profile will also be deleted
campaign_title = models.CharField(max_length=200, blank=True)
Donation model
class Donation(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
# this is many to one relationship, on_deleting user, user's donation details will be set to NULL
campaign = models.ForeignKey(Campaign, on_delete=models.DO_NOTHING)
donation_amount = models.IntegerField()
views.py file
def landing_page(request):
# campaigns = Campaign.objects.all().order_by('-id')
campaigns = Campaign.objects.all().order_by('-id')
////DO SOMETHING HERE TO SHOW TOTAL DONATION AGAINST EACH CAMPAIGN////
return render(request, 'core/landing_page.html',{'campaigns':campaigns})
Using the current views.py file, I'm able to display all the campaigns, how do I pass the total donation against each campaign to the html file?
You can use annotate like this.
from django.db.models import Sum
campaigns = Campaign.objects.annotate(donations=Sum('donation__donation_amount'))
Every compaign object will have a donations attribute with value to sum of total donations for that compaign.

Django - Relationships in Models

In Django there are field types called ForeignKey and OneToMany/OneToOne, I was wondering would I use ForeignKey or the relationship type as the field type in this scenario? User to Profile has been identified as OneToOne but I'm unsure about the others.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
fullname = models.CharField(max_length=100)
dob = models.DateField()
address = models.TextField()
city = models.CharField(max_length=100)
profilephoto = models.ImageField(default='default_profile.jpg', upload_to='reviewApp/static/profile_images')
class Product(models.Model):
name = models.CharField(max_length=100)
brand = models.CharField(max_length=100)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
category = models.CharField(max_length=100)
releasedate = models.DateField()
description = models.TextField()
productphoto = models.ImageField(default='default_product.jpg', upload_to='reviewApp/static/product_images')
class Review(models.Model):
product = models.ForeignKey(Product)
profile = models.ForeignKey(Profile)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = model.PositiveSmallIntegerField(default=1, validators = [MinValueValidator(1), MaxValueValidator(5)])
reviewtext = models.TextField()
postdate = models.DateTimeField(auto_now_add=True)
lastmodified = models.DateTimeField(auto_now=True)
So from what I see here, it seems to be good if the following is what you want:
User can have only one profile and one Profile is related to only one user.
a Profile can make multiple Review but a Review belongs to only one profile.
A Product can have multiple Review but a Review is specific to one Product.
Be carefull to define the on_delete argument for your foreign keys depending of what you want to keep in your database after a delete.
More info from the doc : https://docs.djangoproject.com/fr/2.2/ref/models/fields/#arguments

Categories

Resources