handling many to many relation in django models - python

I am working on a project named "Super Market Inventory Management System". There are some models requiring many-to-many relation among them.
I tried to add ManyToManyField(to=model, on_delete=models.CASCADE). However, it works but I need to add some extra fields to the bridge table between the two tables.
How can I do It?
Given below is my models.py
class Purchase(models.Model):
pay_status = models.CharField(max_length=50, choices=PAYSTATUS_CHOICES, default="Pending")
date_of_purchase = models.DateTimeField(auto_now_add=True)
last_payment = models.DateTimeField(auto_now=True)
class Product(models.Model):
name = models.CharField(max_length=200)
barcode = models.IntegerField(blank=True, null=True)
description = models.TextField(blank=True, null=True)
# image =
weight = models.TextField(blank=True, null=True)
status = models.BooleanField(default=True)
price = models.FloatField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class PurchaseProduct(models.Model):
purchase_id = models.ForeignKey(to=Purchase, on_delete=models.CASCADE)
product_id = models.ForeignKey(to=Product, on_delete=models.CASCADE)
unit_price = models.FloatField()
quantity = models.IntegerField()
price = models.FloatField()
In the bridge table I also want to add the unit price and the quantity how can I do?
OR
Is there any alternate way of doing???
However if I do not add unit price and quantity I don't need to create this bridge table all the endings will be done by Django itself but I must require the above mentioned fields in my model

Related

Filter a user data using contains in Django

I have this model that records data in slug. The user has a relation with the award model. What am trying to do is list all login user's awards slug field data in the contain filter so i can use it to filter user's data.
NOTE : All the data in save in the SuccessfulTransactionHistory model field award is in slug format and SuccessfulTransactionHistory model has no foreign key relation to award and user
models.py
class Award(models.Model):
admin = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='award_images')
slug = models.SlugField(max_length=150, blank=True, null=True)
about_the_award = models.TextField(blank=True, null=True)
status = models.CharField(max_length=20, choices=STATUS_PUBLISHED, default='Closed')
price = models.DecimalField(max_digits=3, default='0.5', decimal_places=1, blank=True, null=True, validators = [MinValueValidator(0.1)])
bulk_voting = models.CharField(max_length=20, choices=BULK_VOTING, default='Closed')
amount = models.DecimalField(default=0.0, max_digits=19, decimal_places=2, blank=True,)
results_status = models.CharField(max_length=20, choices=RESULTS_PUBLISHED, default='private')
starting_date = models.DateTimeField()
ending_date = models.DateTimeField()
date = models.DateTimeField(auto_now_add=True)
class SuccessfulTransactionHistory(models.Model):
nominee_name = models.CharField(max_length=120)
transaction_id = models.CharField(max_length=120)
award = models.CharField(max_length=120)
amount = models.DecimalField(default=0.0, max_digits=19, decimal_places=2)
status = models.CharField(max_length=120, null=True, blank=True)
phone = models.CharField(max_length=120, null=True, blank=True)
date = models.DateTimeField(auto_now_add=True)
In my view.py
success_list = SuccessfulTransactionHistory.objects.filter(award__contains=request.user.award.slug).order_by('-date')
This is my error
'User' object has no attribute 'award'
``
Your User object has a lot of awards, because you use ForeignKey.
The relation is: One award has one User, but One user has one or more than one awards (award_set is the property name).
Solutions? Yes, of course,but depends on the context.
1- If the user has only one award, you can use OneToOneField, and your logic is ok.
2- If the user can have more than one Award, may be you need 2 steps.
Step 1: get all award slugs:
award_slugs = list(request.user.award_set.values_list('slug', flat=True))
where award_slugs is a list of slugs.
Step 2: Get success_list:
success_list = SuccessfulTransactionHistory.objects.filter(award__in=award_slugs)

Django sales campaign model with list of foreign keys that can only appear in one sales campaign?

I want to create a sales campaign which stores a list of books (Items). But the book should only be applied to one sales campaign — ie. it should not be able to appear in two campaigns.
I have the following model:
class Campaign(models.Model):
campaign_name = models.CharField(max_length=50, null=False, blank=False, default='Special Offer')
included_items = models.ManyToManyField(Item, blank=True)
active = models.BooleanField(default=True)
fixed_price = models.DecimalField(max_digits=6, blank=True, null=True, decimal_places=2)
But I think the included_items field might be of the wrong field type. From reading other questions and the Django manual, I think I may be approaching this back to front. Perhaps I should be tackling this from the Item model instead? (Shown below for reference)
class Item(models.Model):
sku = models.CharField(
max_length=10, null=True, blank=True,
default=create_new_sku)
title = models.CharField(max_length=254)
genre = models.ManyToManyField('Genre', blank=True)
author = models.ManyToManyField('Author', blank=True)
description = models.TextField()
age_range = models.ManyToManyField(
'Age_range')
image_url = models.URLField(max_length=1024, null=True, blank=True)
image = models.ImageField(null=True, blank=True)
price = models.DecimalField(max_digits=6, decimal_places=2, default=0.00)
discount = models.DecimalField(max_digits=2, decimal_places=0, default=0)
set_sale_price = models.DecimalField(max_digits=6, decimal_places=2, default=0.00)
original_sale_price = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=True)
final_price = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=False, editable=False)
If each item can only belong to one campaign you should be using a ForeignKey to campaign in the Item model to create your many-to-one relationship
Actually your design is fine.
Using a ForeignKey from #Henty's answer on the Item model still runs into issues where if a campaign becomes inactive (active=False), the Item model needs to nullify the ForeignKey to allow other campaigns to offer it. In addition, an Item model's data should only have information about that instance. To me I think it's weird having a foreign key to a campaign in an Item model since that data is irrelevant to a book. You probably want to read up on data normalization.
That being said, you should manually specify your many-to-many intermediary table as you'll need to apply a unique constraint in it so that only one active campaign can offer the book.
This intermediary table will also have fields such as the discount or sale_price of the book since different campaigns can offer different discounts/prices. I'm assuming price in your Item model is the base retail price on your book so discount, set_sale_price, original_sale_price, and final_price are not needed - again, refer back to data normalization.
In addition, you will need to copy over the active field from your Campaign instance to your intermediary table because it will be needed for the unique constraint. This is done by overriding the save method on your intermediary table to copy over the active value from the Campaign instance.
You'll also have to override the save method on your Campaign model to update the active field on your intermediary instances when you activate/deactivate a campaign.
class Campaign(models.Model):
campaign_name = ...
included_items = models.ManyToManyField(
Item,
through='CampaignItem',
through_fields=('campaign', 'item')
)
active = ...
fixed_price = ...
def save(self, *args, **kwargs):
# pre-save, update associated campaign-item instances
CampaignItem.objects.filter(campaign=self).update(active=self.active)
super().save(*args, **kwargs)
class CampaignItem(models.Model):
campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
active = models.BooleanField(editable=False)
discount = ...
sale_price = ...
# add any other relevant fields related to this campaign item
class Meta:
# add constraint where item can only be in one active campaign
constraints = [
UniqueConstraint(fields=['item'],
condition=Q(active=True),
name='unique_active_item')
]
def save(self, *args, **kwargs):
# copy over the `active` value from campaign
self.active = self.campaign.active
super().save(*args, **kwargs)

What is the best way to handle different but similar models hierarchy in Django?

What is the deal: I'm crating a site where different types of objects will be evaluated, like restaurants, beautysalons, car services (and much more).
At the beginning I start with one app with with Polymorfic Model:
models.py:
from django.db import models
from users.models import ProfileUser
from django.utils import timezone
from polymorphic.models import PolymorphicModel
class Object(PolymorphicModel):
author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
title = models.CharField(max_length=300)
city = models.ForeignKey(City, on_delete=models.CASCADE)
address = models.CharField(max_length=300)
phone = models.CharField(max_length=20, default='')
email = models.CharField(max_length=100, default='')
site = models.CharField(max_length=100, default='')
facebook = models.CharField(max_length=100, default='')
instagram = models.CharField(max_length=100, default='')
content = models.TextField()
rating = models.DecimalField(default=10.0, max_digits=5, decimal_places=2)
created_date = models.DateTimeField(default=timezone.now)
approved_object = models.BooleanField(default=False)
admin_seen = models.BooleanField(default=False)
def __str__(self):
return f"{self.title}"
class Restaurant(Object):
seats = models.IntegerField()
bulgarian_kitchen = models.BooleanField(default=False)
italian_kitchen = models.BooleanField(default=False)
french_kitchen = models.BooleanField(default=False)
sea_food = models.BooleanField(default=False)
is_cash = models.BooleanField(default=False)
is_bank_card = models.BooleanField(default=False)
is_wi_fi = models.BooleanField(default=False)
category_en_name = models.CharField(max_length=100, default='restaurants')
category_bg_name = models.CharField(max_length=100, default='Ресторанти')
bg_name = models.CharField(max_length=100, default='Ресторант')
is_garden = models.BooleanField(default=False)
is_playground = models.BooleanField(default=False)
class SportFitness(Object):
is_fitness_trainer = models.BooleanField(default=False)
category_en_name = models.CharField(max_length=100, default='sportfitness')
category_bg_name = models.CharField(max_length=100, default='Спорт и фитнес')
bg_name = models.CharField(max_length=100, default='Спорт и фитнес')
class CarService(Object):
is_parts_clients = models.BooleanField(default=False)
category_en_name = models.CharField(max_length=100, default='carservice')
category_bg_name = models.CharField(max_length=100, default='Автосервизи')
bg_name = models.CharField(max_length=100, default='Автосервиз')
class Comment(models.Model):
object = models.ForeignKey(Object, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
content = models.TextField()
rating = models.TextField()
approved_object = models.BooleanField(default=False)
admin_seen = models.BooleanField(default=False)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return f"{self.content}"
class Images(models.Model):
object = models.ForeignKey(Object, default=None, on_delete=models.CASCADE)
image = models.ImageField(upload_to='attachments',
verbose_name='Image')
class ObjectCoordinates(models.Model):
object = models.ForeignKey(Object, on_delete=models.CASCADE, related_name='coordinates')
latitude = models.CharField(max_length=60)
longitude = models.CharField(max_length=60)
Don't mention that name Object is wrong, I already know that :)
So all logic about different objects was in one App and this start to cause some problems, like:
views.py:
def show_object(request, category, pk, page_num):
categories = {'restaurants' : 'Restaurant', 'sportfitness' : 'SportFitness', 'carservice' : 'CarService'} # probably this is not good way to do it
obj = apps.get_model('objects', categories[category]).objects.get(id=pk)
def show_all_objects(request, category, page_num, city=None):
params_map = {
'restaurants': Restaurant,
'sportfitness': SportFitness,
'carservice': CarService,
}
objects = Object.objects.instance_of(params_map.get(category))
and other problems in templates (a lot of if-else blocks) etc.
So I decide to change whole structure and put every model in different app, so now I have app:restaurants, app:sportfitness, app:carservices, etc. But it begin to cause some problems, again, like this model:
class ObjectCoordinates(models.Model):
object = models.ForeignKey(Object, on_delete=models.CASCADE, related_name='coordinates')
latitude = models.CharField(max_length=60)
longitude = models.CharField(max_length=60)
All of objects (restaurants, car services) has coordinates of map, so I'm not sure how to handle it, with Model ObjectCoordinates . If I create ObjectCoordinates for each of them, respectively a table in BD (then I will have some tables with different names but same structure, which is not very good, because except ObjectCoordinates, models share and other common models like Images and others, so at the end I will have a lot of tables with different names and same structure). Probably I should add one more column for object category, if I got two rows with same id of objects?
Probably change ObjectCoordinates and other common models to ManyToMany relation will prevent identical tables, but I'm not quite sure about that. Other problem is that there is a lot of repeated code (in views, templates). Also, now, I don't know how to get all objects (restaurants, car services) when they do not have common point, like Object model in first scenario with Polymorphic Model. Or I should keep different apps but to create common Model for all objects, and all of them to to inherit it.
Questions:
What structure is better, first one or second one?
What is the best wayt to implement such site (model structure)?
Should I create common point (model) for all models who they will inherit?
Here is my third attempt (notice that Object is renamed to Venue):
from django.db import models
from users.models import ProfileUser
from django.utils import timezone
from polymorphic.models import PolymorphicModel
# Create your models here.
class City(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return f"{self.name}"
class Category(models.Model):
name = models.CharField(max_length=20)
bg_name = models.CharField(max_length=20, default=None)
category_bg_name = models.CharField(max_length=100, default=None)
def __str__(self):
return f"{self.name}"
class Venue(models.Model):
author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
title = models.CharField(max_length=300)
city = models.ForeignKey(City, on_delete=models.CASCADE)
address = models.CharField(max_length=300)
phone = models.CharField(max_length=20, default='')
email = models.CharField(max_length=100, default='')
site = models.CharField(max_length=100, default='')
facebook = models.CharField(max_length=100, default='')
instagram = models.CharField(max_length=100, default='')
content = models.TextField()
rating = models.DecimalField(default=10.0, max_digits=5, decimal_places=2)
created_date = models.DateTimeField(default=timezone.now)
approved_venue = models.BooleanField(default=False)
admin_seen = models.BooleanField(default=False)
venue_category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category')
def __str__(self):
return f"{self.title}"
class VenueFeatures:
seats = models.IntegerField()
bulgarian_kitchen = models.BooleanField(default=False)
italian_kitchen = models.BooleanField(default=False)
french_kitchen = models.BooleanField(default=False)
sea_food = models.BooleanField(default=False)
is_cash = models.BooleanField(default=False)
is_bank_card = models.BooleanField(default=False)
is_wi_fi = models.BooleanField(default=False)
is_garden = models.BooleanField(default=False)
is_playground = models.BooleanField(default=False)
is_fitness_trainer = models.BooleanField(default=False)
is_parts_clients = models.BooleanField(default=False)
is_hair_salon = models.BooleanField(default=False)
is_laser_epilation = models.BooleanField(default=False)
is_pizza = models.BooleanField(default=False)
is_duner = models.BooleanField(default=False)
is_seats = models.BooleanField(default=False)
is_external_cleaning = models.BooleanField(default=False)
is_internal_cleaning = models.BooleanField(default=False)
is_engine_cleaning = models.BooleanField(default=False)
is_working_weekend = models.BooleanField(default=False)
is_kids_suitable = models.BooleanField(default=False)
is_working_weekend = models.BooleanField(default=False)
venue = models.ForeignKey(Venue, on_delete=models.CASCADE, related_name='venue')
class Comment(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
content = models.TextField()
rating = models.TextField()
approved_venue = models.BooleanField(default=False)
admin_seen = models.BooleanField(default=False)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return f"{self.content}"
class Images(models.Model):
venue = models.ForeignKey(Venue, default=None, on_delete=models.CASCADE)
image = models.ImageField(upload_to='attachments',
verbose_name='Image')
class VenueCoordinates(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.CASCADE, related_name='coordinates')
latitude = models.CharField(max_length=60)
longitude = models.CharField(max_length=60)
Now I do not now how to use Venue with VenueFeatures
Notice that features are just true/false values (checkboxes in form).
Okay, this is probably the best way to abstract anything as much as I can:
from django.db import models
from users.models import ProfileUser
from django.utils import timezone
from polymorphic.models import PolymorphicModel
# Create your models here.
class City(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return f"{self.name}"
class Category(models.Model):
name = models.CharField(max_length=20)
bg_name = models.CharField(max_length=20, default=None)
category_bg_name = models.CharField(max_length=100, default=None)
icon = models.CharField(max_length=40, default=None)
def __str__(self):
return f"{self.name}"
class Venue(models.Model):
author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
title = models.CharField(max_length=300)
city = models.ForeignKey(City, on_delete=models.CASCADE)
address = models.CharField(max_length=300)
phone = models.CharField(max_length=20, default='')
email = models.CharField(max_length=100, default='')
site = models.CharField(max_length=100, default='')
facebook = models.CharField(max_length=100, default='')
instagram = models.CharField(max_length=100, default='')
content = models.TextField()
rating = models.DecimalField(default=10.0, max_digits=5, decimal_places=2)
created_date = models.DateTimeField(default=timezone.now)
approved_venue = models.BooleanField(default=False)
admin_seen = models.BooleanField(default=False)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return f"{self.title}"
class Feature(models.Model):
name = models.CharField(max_length=100)
code = models.CharField(max_length=100 )
category = models.ForeignKey(Category, on_delete=models.CASCADE)
type = models.CharField(max_length=100)
def __str__(self):
return f"{self.name}"
class VenueFeatures(models.Model): # ManyToMany Venues <-> Features
venue = models.ForeignKey(Venue, on_delete=models.CASCADE)
feature = models.ForeignKey(Feature, on_delete=models.CASCADE)
value = models.CharField(max_length=255)
class Comment(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
content = models.TextField()
rating = models.TextField()
approved_venue = models.BooleanField(default=False)
admin_seen = models.BooleanField(default=False)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return f"{self.content}"
class Images(models.Model):
venue = models.ForeignKey(Venue, default=None, on_delete=models.CASCADE)
image = models.ImageField(upload_to='attachments',
verbose_name='Image')
class VenueCoordinates(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.CASCADE, related_name='coordinates')
latitude = models.CharField(max_length=60)
longitude = models.CharField(max_length=60)
Now Features are bound with Categories
Also Venues are ManyToMany with Features
I have already linked it to business logic and it works fine.
TL;DR Use a JSONField (JSONB automatically I think) in PostgreSQL WITHOUT a GIN index for your VenueFeatures instead of creating an entirely new model. Postgres has come a long way towards NoSQL/unstructured DB and it's really good. Using a JSONField in your Venue model would work really well. At the very bottom, I talk about how I would design your site's db.
Although I hate saying this, but this could be the job of a NoSQL database. Usually every application uses RDBM which is structured, but you are using unstructured attributes. You could try using PostgreSQL's JSONB field but... stuffing everything into one field would be tiresome for the GIN index + caching.
For now, I'll ignore a lot of weird practices such as needing to partition a couple of attributes, max_length for char field is typically 255 length for all databases, making sure the most accessed tables don't have too many attributes so that caching is better (i.e. you don't have to invalidate your cache every time a user updates your table), GeoDjango for your coordinate system with the standard Mercator projection system on Postgres Geography mode, and you could use sets instead of dicts (sets are iterables and use {} but nothing is repeated)...
Stay away from this option: For one, I NEVER recommend MongoDB, but it could be useful for you... so long as your application doesn't grow too large as in a couple million records could break your system.
The other RECOMMENDED option is PostgreSQL's JSONB or Django's JSONField withOUT a GIN index (I strongly recommend you don't index this field since venues could change them sooo often to the point that REINDEXING and caching would burn your server and slow your app). It can be useful to store a venue's "Features" inside of this JSONB field since everything is super unstructured.
Lowering the number of attributes is better. You've got A LOT of them too which could slow down querying. I recommend you use Django-cachalot for caching since they support JSONField which can avoid your issue of having a LOT of attributes.
Other recommendations in general
Instead of using default='', just do blank=True, null=True since you're basically saying the user doesn't have to fill out the email field.
Kind of like how you would have a user profile instead of stuffing ALL of your attributes inside of the main User model, you want to partition your Venue data into different models.
The way I would've designed this:
Since you originally had these three venues, just make the "Categories" table into choices.
from django.contrib.gis.db import models # This also imports standard models
from django.contrib.postgres.fields import JSONField # Remember to turn on GeoDjango with PostgreSQL's PostGIS extension
from django.contrib.postgres.indexes import BrinIndex
class Venue(models.Model):
id = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=255)
rating = models.DecimalField(default=10.0, max_digits=5, decimal_places=2)
created_date = models.DateTimeField(default=timezone.now)
approved_venue = models.BooleanField(default=False)
admin_seen = models.BooleanField(default=False)
VENUE_TYPES = [
(1, "restaurant"),
(2, "concert"),
(3, "art night")
]
category = SmallPositiveIntegerField(choices=VENUE_TYPES)
location = models.PointField(srid=4326) # mercator projection from GeoDjango. You don't have to use this; you can stick to your old city and address thing
class Meta:
indexes = (
BrinIndex(fields=['category']), # this is in case you have a LOT of categories later on.
)
class VenueProfile(models.Model):
venue = models.OneToOneField(Venue, on_delete=models.CASCADE, primary_key=True)
misc_features = JSONField() # This field is for stuff like your restaurant features OR your concert features. You can put whatever you want in there. Just make sure you have a list of features that people have when trying to access the JSON so you don't run into exceptions.
created_date = models.DateTimeField(auto_now_add=True)
facebook = models.CharField(max_length=100, blank=True, null=True)
instagram = models.CharField(max_length=100, blank=True, null=True)
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True) # SET_NULL in case you accidentally delete a city. You don't want to also delete the venue.
image = models.ImageField(upload_to='attachments',
verbose_name='Image')
# These attributes are universal for ANY venue so that's why they don't need to be in the JSONField
"""
For the rest of the features, I have no concern EXCEPT for city. Because you're using GeoDjango, you should also use MaxMind's free city database to determine location based on coordinates. That way, you've essentially scraped the need to store the user and such. You could probably save the address field since it could make things easier that a simple coordinate. It's really up to you. You could also use both!
"""
The attributes I've added to the Venue model are THE MOST important things in my opinion that a user would immediately want to know about.
The VenueFeature model is something that isn't updated that much. It's PRIME for using Django-cachalot to take over since it's not modified that often. (50 modifications per second makes invalidation of caches per modification a big hassle).
Comments model is fine.

Django - Database design in orders ecommerce

I have a scenario what will be best design for this .
I have a Articles table (like pizza , drink etc)
class Articles(models.Model):
restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE , blank=True, null=True)
articlename = models.CharField(max_length=50, null=False, blank=False)
price = models.DecimalField(max_digits=10, decimal_places=2)
category = models.ForeignKey(Categories, on_delete=models.CASCADE)
ingredient = models.ManyToManyField(Ingredient) #done
articleoptionnames = models.ForeignKey(ArticlesOptionsName , on_delete=models.CASCADE)
2nd table is Article options (Like topping (1 time, 2times or 3 times), extra sauce , etc)
class ArticlesOptions(models.Model):
articleoptionrestaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE , blank=True, null=True)
optionname = models.ForeignKey(ArticlesOptionsName, on_delete=models.CASCADE, related_name="optionnames")
min = models.IntegerField()
max = models.IntegerField()
choice_price = models.DecimalField(max_digits=10, decimal_places=2)
choice = models.CharField(max_length=255)
def __str__(self):
return str(self.optionname)
And 3rd Order table
class orders(models.Model):
restaurant=models.ForeignKey(Restaurant, on_delete=models.CASCADE , blank=True, null=True)
articles=models.ForeignKey(Articles, on_delete=models.CASCADE , blank=True, null=True)
articleoptions=models.ManyToManyField(ArticlesOptions)
totalamount=models.DecimalField(max_digits=10, decimal_places=2)
def __str__(self):
return str(self.articles)
Customer will be able to purchase many articles at a time and then every article have multipul article options (for example 4 types of topping and 4 type of sauce user can select many type of topping and many type of sauce ). SO how to make order table in best way ?
Your order table should be split down further to be able to accommodate more than one article and article option. Your article options should be related to the article added to the order and not to the order itself. So, in my opinion, I think your order should look like this,
class Orders(models.Model):
restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE, blank=True, null=True)
total_amount = models.DecimalField(max_digits=10, decimal_places=2)
And add an order Article model which has the articles specific to that order each with their own option and each option has a quantity.
class OrderArticle(models.Model):
order = models.ForeignKey(Orders, on_delete=models.CASCADE)
article = models.ForeignKey(Articles, on_delete=models.CASCADE)
class OrderArticleOption(models.Model):
article_option = models.ForeignKey(ArticlesOptions, on_delete=models.CASCADE)
order_article = models.ForeignKey(OrderArticle, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
Hope this helps!

Django models, set unqiue attribute for M2M field per object

Currently, have a database with an Item table and a Stock table. There is a many to many relationship between the two. A single item object can have many sizes. The next step is to assign an 'inStock' options to the item per size.
Any thoughts on acheiving this?
Current models.py
class Stock(models.Model):
size = models.CharField(max_length=30)
stock = models.BooleanField(default=False)
def __str__(self):
return self.size
class Item(models.Model):
title = models.CharField(max_length=250, null=True, unique=True)
price = models.DecimalField(max_digits=8, decimal_places=2)
aw_product_id = models.CharField(max_length=11, null=True) # Removed because multiple products has similar identifer
url = models.URLField(max_length=250) # Removed 'unique=True'as the aw_prod_id will throw an integrity error
image = models.CharField(max_length=1000)
retailer = models.CharField(max_length=250)
category = models.CharField(max_length=100)
featured = models.CharField(max_length=10, default='NO')
gender = models.CharField(max_length=100, null=True)
sizes = models.ManyToManyField(Stock)
uniq_id = models.CharField(max_length=11, null=True, unique=True) # Removed because multiple products has similar identifer
def __str__(self):
return self.title
You can use the through argument to ManyToManyField to specify another model to use for the relationship, with additional fields instead of the autogenerated model that django creates by default.

Categories