Django Cart - multiple configuration options for a product - django

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)

Related

Foreign key with multiple models?

I am creating ecommerce website. There are multiple categories. For example, phones, computers and others. I created a model for each of them. In OrderItems I want to foreign key each of them. So, I want to use multiple models in ForeignKey.
models.py
class Telefon(models.Model):
name = models.CharField(max_length=200)
category = models.CharField(max_length=300, choices=TELEFON, default="xiaomi")
price = models.FloatField()
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.name
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
class TV(models.Model):
name = models.CharField(max_length=200)
category = models.CharField(max_length=300, choices=TELEFON, default="xiaomi")
price = models.FloatField()
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.name
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
Product={'Telefon', 'TV'}
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
#property
def get_total(self):
total = self.product.price * self.quantity
return total
So, how can I use multiple models in Foreign Key field in my OrderItems model.

How to get the product title name in the product image model

How do i access the title field in the product image model so i can upload to specific folder in the media.
class Product(models.Model):
TYPE_CHOICES = (
('T-Shirt', 'T Shirt'),
)
title = models.CharField(max_length=120)
description = models.TextField()
price = models.CharField(max_length=10)
type = models.CharField(max_length=12, choices=TYPE_CHOICES)
bestselling = models.BooleanField()
def __str__(self):
return self.title
class ProductImage(models.Model):
product = models.ForeignKey(Product, related_name='images', on_delete=models.CASCADE)
image = models.ImageField(upload_to='images/' + str(product.))
def __str__(self):
return self.image.url

How to Nested Categories in django admin

I want to create muti category in my ecommerce website where sub category will be dependent on main category.
Please help me with this
class MainCategory(models.Model):
# name = models.CharField(max_length=50)
# date_created = models.DateTimeField(auto_now_add=True)
# def __str__(self):
# return self.name
# class SubCategory(models.Model):
# perentcategory = models.OneToOneField(MainCategory, on_delete=models.CASCADE, primary_key=True)
# name = models.CharField(max_length=50)
# date_created = models.DateTimeField(auto_now_add=True)
# def __str__(self):
# return self.name
# class Items(models.Model):
# main = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
# name = models.CharField(max_length=255)
Posting this question 4th time
Change models.OneToOneField to models.ForeignKey so you can have multiple subcategories assigned to a main category:
class MainCategory(models.Model):
name = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class SubCategory(models.Model):
main_category = models.ForeignKey(MainCategory, on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Items(models.Model):
main = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
You can use single model to accommodate both Category and Sub-categories. Something like this.
class Category(models.Model):
name = models.CharField(blank=False, max_length=200)
slug = models.SlugField(null=False)
parent = models.ForeignKey('self',blank=True, null=True ,related_name='children', on_delete=models.SET_NULL)
Then add following function to the above model
def get_categories(self):
if self.parent is None:
return self.name
else:
return self.parent.get_categories() + ' -> ' + self.name
def __str__(self):
return self.get_categories()
This will return structure similar to this image

Simple Django Model (Add to Cart)

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)
...

Django Model design for a basic inventory application

I am new to Django (and databases for that matter) and trying to create a simple inventory application to help learn. I've been through the tutorials and am going through some books, but I am stuck at what i think is simple, just not sure where to look or how to ask.
With an inventory application, you have your equipment which then has a manufacturer, which the equipment has a model number that only that manufacturer has. Lets say Dell Optiplex 3040. I am also using the admin console right now as well. So i would like to be able to relate equipment to a manufacturer and then also relate the equipment to the model number. It almost seems as I am needing to use the many to many field and the through field to accomplish what I am trying to do but I dont think that is the right way to do it (shown in the link below). https://docs.djangoproject.com/en/1.9/topics/db/models/#many-to-many-relationships
Below is the code I have so far. Thank you.
from django.db import models
# Create your models here.
class Department(models.Model):
department = models.CharField(max_length=50)
def __str__(self):
return self.department
class Manufacturer(models.Model):
manufacturer = models.CharField(max_length=50)
def __str__(self):
return self.manufacturer
class EquipmentModel(models.Model):
equipmentModel = models.CharField(max_length=50)
def __str__(self):
return self.equipmentModel
class Employees(models.Model):
employee_name_first = models.CharField(max_length=25)
employee_name_last = models.CharField(max_length=25)
employee_username = models.CharField(max_length=20)
phone = models.IntegerField()
assigned_equipment = models.ForeignKey('Device', default='undefined')
department = models.ForeignKey('Department', on_delete=models.CASCADE, default='undefined')
job_title = models.ManyToManyField('Job_Positions', default='undefined')
def __str__(self):
return self.employee_username
class Device(models.Model):
ip = models.GenericIPAddressField(protocol='IPv4',unpack_ipv4=False,null=True, blank=True)#might be good to seperate IP in its own class because a device can have multiple IP's
department = models.ForeignKey('Department', on_delete=models.CASCADE)
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
serial_number = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now=False, auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
comments = models.TextField(blank=True)
def __str__(self):
return self.serial_number
class Job_Positions(models.Model):
position_title = models.CharField(max_length=50)
position_description = models.TextField(blank=True)
def __str__(self):
return position_title
***Edit to add the updated code and the admin.py code in response question I had to answer.
#admin.py
from django.contrib import admin
# Register your models here.
from .models import Device,Department,Manufacturer,Employees, Job_Positions, EquipmentModel
class DeviceModelAdmin(admin.ModelAdmin):
list_display = ["ip", "department","model","serial_number","date_updated"]
list_filter = ["department","model","ip"]
search_fields = ["ip"]
class Meta:
model = Device
class EmployeesModelAdmin(admin.ModelAdmin):
list_display = ["employee_name_first", "employee_name_last", "employee_username", "phone"]
list_filter = ["department"]
class Meta:
model = Employees
admin.site.register(Device, DeviceModelAdmin)
admin.site.register(Department)
admin.site.register(Manufacturer)
admin.site.register(EquipmentModel)
admin.site.register(Employees, EmployeesModelAdmin)
admin.site.register(Job_Positions)
updated models.py
from django.db import models
# Create your models here.
class Department(models.Model):
department = models.CharField(max_length=50)
def __str__(self):
return self.department
class Manufacturer(models.Model):
manufacturer = models.CharField(max_length=50)
def __str__(self):
return self.manufacturer
class EquipmentModel(models.Model):
model_number = models.CharField(max_length=50)
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
def __str__(self):
return self.model_number
class Employees(models.Model):
employee_name_first = models.CharField(max_length=25)
employee_name_last = models.CharField(max_length=25)
employee_username = models.CharField(max_length=20)
phone = models.IntegerField()
assigned_equipment = models.ForeignKey('Device', default='undefined')
department = models.ForeignKey('Department', on_delete=models.CASCADE, default='undefined')
job_title = models.ManyToManyField('Job_Positions', default='undefined')
def __str__(self):
return self.employee_username
class Device(models.Model):
ip = models.GenericIPAddressField(protocol='IPv4',unpack_ipv4=False,null=True, blank=True)#might be good to seperate IP in its own class because a device can have multiple IP's
department = models.ForeignKey('Department', on_delete=models.CASCADE)
model = models.ForeignKey('EquipmentModel', on_delete=models.CASCADE,null=True)
serial_number = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now=False, auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
comments = models.TextField(blank=True)
def __str__(self):
return self.serial_number
class Job_Positions(models.Model):
position_title = models.CharField(max_length=50)
position_description = models.TextField(blank=True)
def __str__(self):
return position_title
A many-to-many relationship is not what you want here, because any piece of equipment (I assume) can only have one manufacturer.
You do need an intermediate model which stores the model information, and you already have one in your EquipmentModel. I would suggest modifying it as follows:
class EquipmentModel(models.Model):
# This stores information about a particular model of device
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
model_number = models.CharField(max_length=50)
And then instead of having a foreign key to the manufacturer in Device, replace it with a foreign key to the equipment model:
class Device(models.Model):
# ...
model = models.ForeignKey('EquipmentModel', on_delete=models.CASCADE)