I am planning to develop a virtual shopping mall where stores of any kind can be registered, such as in a physical shopping mall. First I want to develop an efficient and effective database modeling for products and stores only. I wanted it be very flexible and user friendly. Here is the model design for Product
and Store
. How can I improve the database design?
My concern is mainly for the categories be user friendly. For example Men -> Clothing -> Shirts
as a category. If you wish, you can help me to improve the design as well, I would appreciate all recommendations.
I am using Python 3 and Django 1.11.
DAY = (( 'Sun', 'Sunday'),
( 'Mon', 'Monday'),
( 'Tue', 'Tuesday'),
( 'Wed', 'Wednesday'),
( 'Thu', 'Thursday'),
( 'Fri', 'Friday'),
( 'Sat', 'Saturday')
)
class OpeningHours(models.Model):
store = models.ForeignKey('Store', related_name="opening_hour")
weekday = models.CharField(choices=DAY, max_length=12)
opening_hour = models.TimeField()
closing_hour = models.TimeField()
class Meta:
verbose_name = 'Opening Hour'
verbose_name_plural = 'Opening Hours'
def ___str__(self):
return '{} {} - {}'.format(self.weekday, str(self.opening_hour), str(self.closing_hour))
class Store(models.Model):
merchant = models.ForeignKey(User, blank=True, null=False)
token = models.CharField(default=token_generator, max_length=20, unique=True, editable=False)
name_of_legal_entity = models.CharField(max_length=250, blank=False, null=False)
pan_number = models.CharField(max_length=20, blank=False, null=False)
registered_office_address = models.CharField(max_length=200)
name_of_store = models.CharField(max_length=100)
email = models.EmailField(blank=False, null=False)
store_contact_number = models.PositiveIntegerField(blank=False, null=False)
# store_long = models.DecimalField(max_digits=12, decimal_places=8, null=True)
# store_lat = models.DecimalField(max_digits=12, decimal_places=8, null=True)
is_active = models.BooleanField(default=True)
class Meta:
verbose_name = 'Store'
def __str__(self):
return self.name_of_store
class Meta:
verbose_name = 'Store'
verbose_name_plural = 'Stores'
class Product(models.Model):
store = models.ForeignKey(Store)
token = models.CharField(default=token_generator, max_length=20, unique=True, editable=False)
category = models.ForeignKey('CatalogCategory', related_name='products')
brand = models.ForeignKey('Brand', related_name="product_brand")
image = models.ImageField(upload_to='products/images/')
name_of_product = models.CharField(max_length=120, blank=False,null=False)
description = models.TextField(blank=False,null=False)
price = models.DecimalField(decimal_places=2, max_digits=20)
discount = models.DecimalField(decimal_places=2, max_digits=20)
sales_price = models.DecimalField(decimal_places=2, max_digits=20)
is_active = models.BooleanField(default=True)
is_gurantee_available = models.BooleanField(default=False)
is_negotiated = models.BooleanField(default=False)
is_verified = models.BooleanField(default=False)
is_instock = models.BooleanField(default=False)
def __str__(self):
return self.name_of_product
class Meta:
verbose_name = 'Product'
verbose_name_plural = 'Products'
class Brand(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
logo = models.ImageField(upload_to='products/brand/images/')
class Meta:
verbose_name = 'Brand'
verbose_name_plural = 'Brands'
def __str__(self):
return self.name
class Variation(models.Model):
VAR_CATEGORIES = (
('size', 'size'),
('color', 'color'),
)
product = models.ForeignKey(Product)
token = models.CharField(default=token_generator, max_length=20, unique=True, editable=False)
category = models.CharField(max_length=10, choices=VAR_CATEGORIES)
title = models.CharField(max_length=50)
price = models.DecimalField(decimal_places=2, max_digits=20)
discount = models.DecimalField(blank=True ,null =True, decimal_places=2, max_digits=20)
active = models.BooleanField(default=True)
quantity = models.IntegerField(null=True , blank=True)
sales_price = models.DecimalField(blank=True ,null =True, decimal_places=2, max_digits=20)
image = models.ImageField(upload_to='products/images/')
class Meta:
verbose_name = 'Variation'
verbose_name_plural = 'Variations'
def __str__(self):
return '{0} of {1} from {2}' .format(self.product.name_of_product, self.title, self.product.store.name_of_store)
class CatalogCategory(models.Model):
token = models.CharField(default=token_generator, max_length=20, unique=True, editable=False)
parent = models.ForeignKey('self', blank=True, null=True, related_name='children')
name = models.CharField(max_length=300)
description = models.TextField(blank=True)
class Meta:
verbose_name = 'CatalogCategory'
verbose_name_plural = 'CatalogCategories'
def __str__(self):
return self.name
class ProductImage(models.Model):
product = models.ForeignKey(Product, null=True, blank=True, related_name="product_image")
image = models.ImageField(upload_to='products/images/')
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
@property
def imageName(self):
return str(os.path.basename(self.image.name))
def __str__(self):
return str(self.image)
class Meta:
verbose_name = 'Product Image'
verbose_name_plural = 'Product Images'
class StoreCategory(models.Model):
STORE_CATEGORIES= (
('GROCERY', ('Grocery')),
('MEATS', ('Meats')),
('FOODS & BEVERAGES', ('Foods')),
('COMPUTERS', ('Computers')),
('ELECTRONICS', ('Electronics')),
('HOME & OUTDOOR', ('Home & Outdoor')),
('FASHION & BEAUTY', ('Fashion & Beauty')),
('HEALTH', ('Health')),
('SPORTS & FITNESS', ('Sports & Fitness')),
('BABY', ('Baby')),
('BOOKS', ('Books')),
)
product = models.ForeignKey(Product,null=True, on_delete=models.CASCADE)
store_category = models.CharField(choices=STORE_CATEGORIES, default='GROCERY', max_length=30)
# objects = VariationManager()
class Meta:
verbose_name = 'Store Category'
verbose_name_plural = 'Store Categories'
def __str__(self):
# return str(self.product.name_of_product)
return '{0} of category {1}' .format(self.product.name_of_product, str(self.store_category))