Simple Django Model (Add to Cart) - django

This is my first Django project and I am trying to implement add-to-cart features.
What changes should I make in this model so that multiple "Item" can be added into "Order", and also keep track of item quantity?
from django.db import models
from django.utils import timezone
# Create your models here.
class Order(models.Model):
customer = models.ForeignKey('Customer')
ordered_item = models.ForeignKey('OrderQuantity', on_delete=models.CASCADE, null=True)
address = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
class Customer(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
phone = models.CharField(max_length=50)
def __str__(self):
return self.first_name
class Item(models.Model):
name = models.CharField(max_length=50)
price = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)
description = models.TextField(null=True)
summary = models.TextField(null=True)
type = models.CharField(max_length=50, null=True)
brand = models.CharField(max_length=50, null=True)
weight = models.DecimalField(default=0.00, max_digits=100, decimal_places=3)
picture = models.ImageField(null=True, upload_to='images/')
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.name
class OrderQuantity(models.Model):
product = models.ForeignKey('Item')
quantity = models.PositiveIntegerField()

You need to create ManyToManyField in Order Model
class Order(models.Model):
customer = models.ForeignKey('Customer')
ordered_item = models.ForeignKey('OrderQuantity', on_delete=models.CASCADE, null=True)
address = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
items = models.ManyToManyField(Item)
Then you can add items to order in this way:
someorder.items.add(someItem)

Use ManyToManyField in your Item Model
class Item(models.Model):
orders = models.ManyToManyField(Order)
---
So one item have many orders. You can access it by order.item_set or item.orders

It depends on what your Item model is.
If Item is contains a type of product - you may want to use many-to-many field in your Order model, like so:
class Order(models.Model):
...
items = models.ManyToManyField(Item)
...
If Item describes one real item (not type of items), the proper way would be using ForeignKey in your Item model:
class Item(models.Model):
...
order = models.ForeignKey(Order)
...

Related

Django: handle multi stock (related table) in Product Based List View

I need to manage Products shared by multiple Warehouses.
I tried to get through with annotate, prefetch_related, select_related but in my case, those solutions are upside-down for my need. I need first to get product and then, the related stock in each warehouse and display it in template and the foreignKey is in my Sststock, not in Product
I have :
Product models.py
class Product(models.Model):
famille = models.ForeignKey(Famille, on_delete=SET_NULL, null=True)
sku = models.CharField(max_length=100, unique=True)
nom = models.CharField(max_length=250)
fournisseur = models.ForeignKey(
Supplier, on_delete=models.SET_NULL, default=12, null=True)
qty = models.IntegerField()
mini = models.IntegerField()
maxi = models.IntegerField()
[...]
Warehouse models.py
class Warehouse(models.Model):
nom = models.CharField(max_length=100)
code = models.CharField(max_length=10, null=True)
adresse = models.CharField(max_length=255)
cp = models.IntegerField()
ville = models.CharField(max_length=50)
tel = models.CharField(max_length=10)
email = models.EmailField(default='sav#iturbo.fr', null=False, blank=False)
allow_store = models.BooleanField(default=False)
def __str__(self):
return self.nom.upper()
Sststock models.py
class SstStock(models.Model):
sst = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
mageid = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)
qty = models.IntegerField()
last_update = models.DateTimeField(default=timezone.now)
For the time, I only have 3 warehouses but there could have more in the future.
First I had "hard-coded" my 3 warehouses in Product's model but this solution was not easily scalable.
What would be the best way to achieve my goal ?
I've seen solution with Mysql Stored Procedures in PhpMyAdmin for creating innerJoin tables but there is maybe possibilities within Django.

How to add Category while adding product in Django form? Just like the Django admin form

So I am trying to build an inventory system.
I have 2 models, Categories and Product connected through the ManyToMany field.
I want to add a category while I am adding the product just like it happens in the Django admin form.
How can I do that?
My model.py File
class Categories(models.Model):
name = models.CharField(max_length=30)
organisation = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
def __str__(self):
return f"{self.name}"
class Product(models.Model):
category = models.ManyToManyField(Categories)
brand = models.CharField(max_length=20)
model = models.CharField(max_length=20)
hac = models.CharField(max_length=20, null=True, blank=True)
rate = models.DecimalField(max_digits=6, decimal_places=2)
stock = models.IntegerField(default=0)
# organisation = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
date_added = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.brand} {self.model} "
My form.py file
class ProductModelForm(forms.ModelForm):
class Meta:
model = Product
fields = '__all__'
**My code output **
See the below screenshots to understand what I want to do. I basically want that plus button option to add a category from the product form itself.
You should show snippets of codes that we need to provide an answer.

labeling in Django Admin

I am new to Django and still learning, I have created a database and some models but I got stuck with meaningful labels in Django Admin. This is the model:
class Product(models.Model):
product_id = models.AutoField(primary_key=True)
product_name = models.CharField(max_length= 50)
brand_name = models.CharField(max_length = 20)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
min_order = models.IntegerField()
max_order = models.IntegerField()
units = models.IntegerField()
quantity = models.ForeignKey(Quantity, on_delete=models.SET_NULL, null=True)
objects = ProductManager()
class Meta:
verbose_name = "Product"
verbose_name_plural = 'Products'
And I get this:
I want Product object (3) to be replaced byt the product_name. Thank you in advance!
You can override the __str__ method [python-doc] and return the product_name instead:
class Product(models.Model):
# …
def __str__(self):
return self.product_name

Django Cart - multiple configuration options for a product

I want to create a Django web-application where users can add items to a cart.
Without the models Colour and Size this works so far.
My Problem is, that i can not figure out how to implement the configuration-options (for example) Colour and Size the right way.
I added both "Options" with a Many-to-One relationship. I now can add multiple colours and sizes for a Product, but do not know how to save the choosen "Option" in an CartEntry
This is what i got so far:
from django.db import models
from django.contrib.auth.models import User
class Product(models.Model):
name = models.CharField(max_length=256)
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return str(self.name)
class Colour(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="rel_colour")
option = models.CharField(max_length=24)
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return str(self.colour)
class Size(models.Model):
product =models.ForeignKey(Product, on_delete=models.CASCADE, related_name="rel_size")
option = models.CharField(max_length=24)
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return str(self.size)
class Cart(models.Model):
user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
products = models.ManyToManyField(Product, blank=True)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.id) + ' - ' + str(self.user)
class CartEntry(models.Model):
product = models.ForeignKey(Product, null=True, on_delete=models.CASCADE)
cart = models.ForeignKey(Cart, null=True, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
def __str__(self):
return str(self.quantity) + ', ' + str(self.product.name)
Maybe i can not user relations for CartEntry here?
why not do like this:
from django.db import models
from django.contrib.auth.models import User
class Product(models.Model):
name = models.CharField(max_length=256)
colour = models.ForeignKey(Colour, on_delete=models.CASCADE)
size = models.ForeignKey(Size, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return str(self.name)
class Colour(models.Model):
name = models.CharField(max_length=24)
def __str__(self):
return str(self.name)
class Size(models.Model):
name = models.CharField(max_length=24)
def __str__(self):
return str(self.name)
so every product has different colour and size. or if you want make a Product as a "parent" you can add 1 more model like let say VariantProduct
class Product(models.Model):
name = models.CharField(max_length=256)
def __str__(self):
return str(self.name)
class VariantProduct(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
name = models.CharField(max_length=256)
colour = models.ForeignKey(Colour, on_delete=models.CASCADE)
size = models.ForeignKey(Size, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return str(self.name)

django charge users based on how many counties they want to access

I'm building a web app,
basically I currently have 3 models ,
1- State: which represents all US states
2- County: which represents all counties with foreign key of state
3- Home: which represents all homes with foreign key of County
the app will show homes,
but users needs to subscribe for certain counties (the counties prices can vary)
the goal is : when users subscribe to certain counties they can see the related "Homes" to these counties
I'm not sure how should I represent these relations between users, subscriptions and how to connect it to County model I have.
and how to make a view for the user to add new counties.
Thank you.
Update (My models):
class State(models.Model):
state_name = models.CharField(max_length=50)
def __str__(self):
return self.state_name
class County(models.Model):
county_name = models.CharField(max_length=50)
state = models.ForeignKey(State, on_delete=models.CASCADE)
def __str__(self):
return self.county_name
class Meta:
unique_together = ("county_name", "state")
verbose_name_plural = 'Counties'
class Home(models.Model):
owner_name = models.CharField(max_length=100, null=True, blank=True)
street_address = models.CharField(max_length=100, null=True, blank=True)
city = models.CharField(max_length=50, null=True, blank=True)
county = models.ForeignKey(County, on_delete=models.CASCADE)
postal_code = models.CharField(max_length=50, null=True, blank=True)
price = models.CharField(max_length=50, null=True, blank=True)
sqft = models.CharField(max_length=50, null=True, blank=True)
home_type = models.CharField(max_length=100, null=True, blank=True)
geom = models.PointField()
added = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return '{}, {}, {}'.format(self.street_address, self.city, self.county.state.state_name)
class Meta:
verbose_name = 'Home'
verbose_name_plural = 'Homes'
#property
def state_county(self):
return f'{self.county.county_name}_{self.state}'
#property
def state(self):
return self.county.state.state_name
Here is a basic idea, you should evaluate from this point.
class State(models.Model)
name = models.CharField(max_length=100)
class County(models.Model)
state = models.ForeignKey(State)
name = models.CharField(max_length=100)
class Home(models.Model)
county= models.ForeignKey(County)
name = models.CharField(max_length=100)
class Subscription(models.Model)
county = models.ForeignKey(County)
user = models.ForeignKey(User)
Basically, you can then charge your user per County (observe that one can have more than one County subscription)
Another aproach would be to use a hierarchy to have State>County>Home, on a MPTT, but maybe its not what you want.
One way would be to add ManyToMany County relationship field in the Subscriptions model and then you would query subscribed county and filter Home.
Something in the sense of:
class County(models.Model):
county = models.CharField(max_length=255)
class Home(models.Model):
county = models.ForeignKey(County, on_delete=models.PROTECT)
class Subscription(models.Model):
user = models.ForeingKey(User, on_delete=models.PROTECT)
county = models.ManyToMany(County)
Then you'd query subscriptions and filter based on that.
subscriptions = Subscription.objects.filter(user=request.user).values_list('county', flat=True)
homes = Home.objects.filter(county_id__in=subscriptions)
You could further improved that with models Manager on Subscription to avoid filtering user every time with something like:
class SubscriptionManager(models.Manager):
def user_subscriptions(self, user):
return super().get_queryset().filter(user=user)
class Subscription(models.Model):
user = models.ForeingKey(User, on_delete=models.PROTECT)
county = models.ManyToMany(County)
objects = SubscriptionManager()
and then filter either with:
subscriptions = Subscription.objects.filter(user=request.user).values_list('county', flat=True)
or
subscriptions = Subscription.objects.user_subscriptions(request.user).values_list('county', flat=True)