7
\$\begingroup\$

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))
Phrancis
20.5k6 gold badges69 silver badges155 bronze badges
asked Aug 29, 2017 at 4:26
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

The models look about right.

def imageName(self):

Well, ok, PEP-8 asks that you spell this image_name, but, whatever, I'm sure you had other constraints you were working within.

In STORE_CATEGORIES I don't understand why Foods is special. It otherwise has DRY issues that could be addressed by applying .upper() or .title() to a single copy of the list.

Looks good to me. Ship it!

answered Apr 1, 2019 at 6:20
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.