user Checkout and guest checkout: best way to use both in Django - python

Actually I need suggestion about best practice to handle guest checkout and customer checkout.
I have a scenario that 1 order can have multipul products (which is not problem). My order table is like
class Orders(models.Model):
customer= models.ForeignKey(Customer, on_delete=models.CASCADE)
order_number = models.AutoField(primary_key=True)
total_amount = models.DecimalField(max_digits=10, decimal_places=2)
ordertime = models.DateTimeField(auto_now_add=True)
order_status = models.CharField(max_length=50)
is_placed = models.BooleanField(default=False)
and then it is linked to product table like this
class OrderProduct(models.Model):
order=models.ForeignKey(Orders, on_delete=models.CASCADE)
activity = models.ForeignKey(ActivityOrganizer, on_delete=models.CASCADE)
participants=models.IntegerField(default=0)
totalPrice=models.DecimalField(max_digits=10, decimal_places=2)
checkIn = models.DateField()
language = models.CharField(max_length=50, null=False, blank=False)
And my Customer Table is
class Customer(models.Model):
customerProfile = models.OneToOneField(User, on_delete=models.CASCADE)
first_name=models.CharField(max_length=50, null=False, blank=False)
last_name=models.CharField(max_length=50, null=False, blank=False)
email=models.CharField(max_length=50, null=False, blank=False)
mobile_number=models.CharField(max_length=50, null=False, blank=False)
profile_image=models.ImageField(null=True, upload_to='CustomerProfile')
is_customer=models.BooleanField(default=False)
city=models.CharField(max_length=50, null=True, blank=True)
gender=models.CharField(max_length=50, null=True, blank=True)
verification_key = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return str(self.first_name)
Now I want to Enable guest checkouts aswell . then Should I use existing tables of order by allowing Foregin key Null ? Or I should make seprate order tables for this ? What will be best way ?

Based off the information you've presented, I'd make Customer.customerProfile nullable and have it set to None for guest checkouts.

Related

Two dependent conditions in exclude DJANGO

I want to check whether the current user already has the same movie id in his personal list or not. If he has it then I want to exclude that movie from my trending list.
I want it to be something like this.
views.py
trending = list(Movies.objects.exclude(mid in mymovies WHERE uid = request.user.id))
models.py
class Movies(models.Model):
mid = models.CharField(max_length=255, primary_key=True)
title = models.CharField(max_length=255, null=True, blank=True)
rating = models.CharField(max_length=5, null=True, blank=True)
type = models.CharField(max_length=255, null=True, blank=True)
genre = models.CharField(max_length=255, null=True, blank=True)
rdate = models.CharField(max_length=255, null=True, blank=True)
language = models.CharField(max_length=255, null=True, blank=True)
cover = models.CharField(max_length=255, null=True, blank=True)
description = models.TextField(null=True, blank=True)
sequal = models.CharField(max_length=255, null=True, blank=True)
trailer = models.CharField(max_length=255, null=True, blank=True)
year = models.CharField(max_length=5, null=True, blank=True)
objects = models.Manager()
def __str__(self) -> str:
return self.title
class MyMovies(models.Model):
mid = models.ForeignKey(Movies, on_delete=CASCADE)
uid = models.ForeignKey(User, on_delete=CASCADE, null=True, blank=True)
watched = models.BooleanField()
date = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
You can .exclude(…) with:
trending = Movies.objects.exclude(mymovies__uid=request.user)
If you specified a related_query_name=… [Django-doc] or a related_name=… [Django-doc], then you need to use that to make a JOIN with your Movies model:
trending = Movies.objects.exclude(related_name_of_fk__uid=request.user)
Note: normally a Django model is given a singular name, so MyMovie instead of MyMovies.
Note: Normally one does not add a suffix _id to a ForeignKey field, since Django
will automatically add a "twin" field with an _id suffix. Therefore it should
be user, instead of uid.

How to write a self referencing Django Model?

I have a Django model "Inspection" which has:
InspectionID (PK)
PartID
SiteID
Date
Comment
Report
Signiture
I want to be able to have a one to many relationship between the inspection ID and date. So one ID can have inspections at many dates. How would I do this? I currently have the following:
class Inspection(models.Model):
InspectionID = models.IntegerField(primary_key=True, unique=True)
PartID = models.ForeignKey('Part', on_delete=models.CASCADE)
SiteID = models.ForeignKey('Site', on_delete=models.CASCADE)
Date = models.DateField(auto_now=False, auto_now_add=False)
Comment = models.CharField(max_length=255, blank=True)
Report = models.FileField(upload_to='docs', null=True, blank=True)
Signiture = models.CharField(max_length=255, blank=True)
I thought about using models.ForeignKey but I really don't know how to implement that properly in this situation.
I want to be able to have a one to many relationship between the inspection ID and date.
You create an extra model, like:
class InspectionDate(models.Model):
inspection = models.ForeignKey(
Inspection,
on_delete=models.CASCADE,
related_name='inspectiondates'
)
date = models.DateField()
You thus can create InspectionDates for a given Inspection.
Or if you want to add extra data, it might be better to define an InspectionGroup model:
class InspectionGroup(models.Model):
pass
class Inspection(models.Model):
id = models.AutoField(primary_key=True, unique=True, db_column='InspectionId')
inspectiongroup = models.ForeignKey(InspectionGroup, on_delete=models.CASCADE, db_column='InspectionGroupId')
part = models.ForeignKey('Part', on_delete=models.CASCADE, db_column='PartId')
site = models.ForeignKey('Site', on_delete=models.CASCADE, db_column='SiteId')
date = models.DateField(db_column='Date')
comment = models.CharField(max_length=255, blank=True, db_column='CommentId')
report = models.FileField(upload_to='docs', null=True, blank=True, db_column='ReportId')
signiture = models.CharField(max_length=255, blank=True, db_column='Signature')
Note: the name of attributes are normally written in snake_case [wiki], not in PerlCase or camelCase.
you may store 'self Foriegnkey' as
class Inspection(models.Model):
InspectionID = models.IntegerField(primary_key=True, unique=True)
PartID = models.ForeignKey('Part', on_delete=models.CASCADE)
SiteID = models.ForeignKey('Site', on_delete=models.CASCADE)
Date = models.DateField(auto_now=False, auto_now_add=False)
Comment = models.CharField(max_length=255, blank=True)
Report = models.FileField(upload_to='docs', null=True, blank=True)
Signiture = models.CharField(max_length=255, blank=True)
inspection_id = models.ForeignKey('self', null=True, blank=True)

referral by company's product specific and company specific

I am thinking of creating a referral and reward app where a user will list his/her company with the product they have. A company can use referral program by product specific or just in whole(could not name it properly). For example, I have listed my company called ABC Company and I have a product like smartphone, smart Tvs, Laptops. I would like to market for my company by just saying refer me to 10 people and get something in return(this is non-product specific) or I should be able to market my specific product let's say when user goes to the abc phone XI and there will be refer this phone and get the same phone in return if you refer to more than 50 or if more than 10 then 10% discount etc. This is just an example to demonstrate my project.
For now I created the model for Company, Product(with nested category), referral. But I have no idea on how should i be able to keep the referral based on above example like product specific or based on full company.
Here is what I have done
class Product(models.Model):
"""
product model
"""
name = models.CharField(max_length=100, blank=True)
company = models.ForeignKey(Company, blank=False, null=False, on_delete=models.CASCADE)
category = TreeForeignKey('Category', null=True, blank=True, db_index=True, on_delete=models.CASCADE)
image = models.FileField(upload_to='/company/', max_length=100, blank=True, null=True)
description = models.TextField(blank=True, null=True)
stocks = models.IntegerField(default=0, blank=True)
class Company(models.Model):
"""
company model
"""
name = models.CharField(max_length=150, blank=False, null=False)
domain = models.URLField(blank=False, null=False)
email = models.EmailField()
description = models.TextField(blank=True)
pan_number = models.CharField(max_length=100, blank=False, null=False)
industry = models.CharField(max_length=150, blank=False, null=False)
class Join(models.Model):
"""
Join Model
"""
email = models.EmailField()
friend = models.ForeignKey("self", related_name='referral', null=True, blank=True, on_delete=models.CASCADE)
ref_id = models.CharField(max_length=120, default='ABC', unique=True)
count_added = models.ForeignKey("self", null=True, related_name='count', blank=True, on_delete=models.CASCADE)
ip_address = models.CharField(max_length=120, default='ABC')
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return '{}'.format(self.email)

show forms for model who can have multiple instance

I am creating a simple project which is about creating a resume by user. In resume, a user can have multiple experience, educational background and etc. That is why I have created the following table where experience, educational background, skills are foreignkey to the resume table.
class Resume(models.Model):
applicant = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=100, blank=False, null=False, help_text="Full Name")
slug = models.SlugField(max_length=50, unique=True)
designation = models.CharField(max_length=200, blank=True, null=True)
city = models.CharField(max_length=100, blank=True, null=True)
def __str__(self):
return self.name
class Education(models.Model):
resume = models.ForeignKey(Resume, related_name='education')
name = models.CharField(max_length=100, blank=False, null=False, help_text="Name of an institution")
course = models.CharField(max_length=200, blank=False, null=False, help_text="Name of a course")
description = models.CharField(max_length=400, blank=True, null=True)
start_date = models.DateField()
end_date = models.DateField()
class Experience(models.Model):
resume = models.ForeignKey(Resume, related_name='experience')
designation = models.CharField(max_length=100, blank=True, null=True)
company = models.CharField(max_length=100, blank=True, null=True)
description=models.CharField(max_length=400, blank=True, null=True)
start_date = models.DateField()
end_date = models.DateField()
class Skill(models.Model):
resume=models.ForeignKey(Resume, related_name="skills")
name = models.CharField(max_length=100, blank=True, null=True, help_text="Name of the skill")
class Meta:
verbose_name='Skill'
verbose_name_plural='Skills'
def __str__(self):
return self.name
Now for such situation, do I have to create a ResumeForm, EducationForm, ExperienceForm etc and create an Education, Experience and Skill formset or
I have to do something else. I do not have clear idea on how to move forward now for developing form with such
relation where Education, Skill can have multiple instance. Can anyone guide me, please?
Well the question is unclear but following with your idea you have 2 options:
First you can have existing values in Education, Experience, Skill. Then in the view you have a checkbox to add education, experience, skill.
Second you can add education, experience, skill creating a modelForm for each one and then passing the resume, It is not necessary use formset here

Pk fields always ends up in resulting query GROUP BY clause

I have my model hierarchy defined as follows:
class Meal(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
discount_price = models.DecimalField(blank=False, null=False, decimal_places=2, max_digits=4)
normal_price = models.DecimalField(blank=True, null=True, decimal_places=2, max_digits=4)
available_count = models.IntegerField(blank=False, null=False)
name = models.CharField(blank=False, null=False, max_length=255)
active = models.BooleanField(blank=False, null=False, default=True)
class Order(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
number = models.CharField(max_length=64, blank=True, null=True)
buyer_phone = models.CharField(max_length=32, blank=False, null=False)
buyer_email = models.CharField(max_length=64, blank=False, null=False)
pickup_time = models.DateTimeField(blank=False, null=False)
taken = models.BooleanField(blank=False, null=False, default=False)
class OrderItem(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='items')
meal = models.ForeignKey(Meal, on_delete=models.CASCADE)
amount = models.IntegerField(blank=False, null=False, default=1)
I'm trying to get some statistics about orders and I came up with django orm call that looks like this:
queryset.filter(created_at__range=[date_start, date_end])\
.annotate(price=Sum(F('items__meal__discount_price') * F('items__amount'), output_field=DecimalField()))
.annotate(created_at_date=TruncDate('created_at'))\
.annotate(amount=Sum('items__amount'))\
.values('created_at_date', 'price', 'amount')
The above however doesn't give me the expected results, because for some reason the id column still ends up in the GROUP BY clause of sql query. Any help with that?
To make it work I had to do the following:
qs.filter(created_at__range=[date_start, date_end])\
.annotate(created_at_date=TruncDate('created_at'))\
.values('created_at_date')\
.annotate(price=Sum(F('items__meal__discount_price') * F('items__amount'),
output_field=DecimalField()))
.annotate(amount=Sum('items__amount'))
Which kind of makes sense - I pull only the created_at field, transform it and then annotate the result with two other fields.

Categories