diff --git a/shop/admin.py b/shop/admin.py index 8c38f3f..af9ed81 100644 --- a/shop/admin.py +++ b/shop/admin.py @@ -1,3 +1,44 @@ from django.contrib import admin +from shop import models -# Register your models here. + +@admin.register(models.Product) +class ProductAdmin(admin.ModelAdmin): + ''' + This class is for managing products from admin panel. + ''' + + list_display = ['owner', 'title', 'category', 'price', 'available'] + list_filter = ['owner', 'category', 'available'] + search_fields = ['title__icontains', 'description__icontains', 'price__icontains'] + fields = ['cover', 'title', 'slug', 'description', 'price', 'category', 'available'] + readonly_fields = ['owner'] + list_per_page = 10 + prepopulated_fields = { + 'slug': ('title',) + } + + def save_model(self, request, obj, form, change): + # change owner field to owner requested + obj.owner = request.user + return super().save_model(request, obj, form, change) + + +@admin.register(models.Category) +class CategoryAdmin(admin.ModelAdmin): + ''' + This class is for managing categories from admin panel. + ''' + + list_display = ['owner', 'label'] + fields = ['label', 'slug'] + readonly_fields = ['owner'] + list_per_page = 10 + prepopulated_fields = { + 'slug': ('label',) + } + + def save_model(self, request, obj, form, change): + # change owner field to owner requested + obj.owner = request.user + return super().save_model(request, obj, form, change) diff --git a/shop/models.py b/shop/models.py index 71a8362..29b0589 100644 --- a/shop/models.py +++ b/shop/models.py @@ -1,3 +1,78 @@ from django.db import models +from django.contrib.auth import get_user_model +from django.utils.text import slugify -# Create your models here. +from utils.validator import english_character_regex + + +User = get_user_model() + +class Product(models.Model): + ''' + This class is for creating Product. + ''' + + # initial information fields about product + cover = models.ImageField(upload_to='products/%Y/%m/%d/', blank=True) + title = models.CharField(max_length=200, unique=True, validators=[english_character_regex]) + slug = models.CharField(max_length=200, unique=True) + description = models.TextField(blank=True) + price = models.DecimalField(max_digits=10, decimal_places=2) + available = models.BooleanField(default=True) + + # relationship with other models + owner = models.ForeignKey(User, on_delete=models.CASCADE) + category = models.ForeignKey('Category', related_name='product_category', on_delete=models.CASCADE) + + # create & update fields + create_at = models.DateTimeField(auto_now_add=True) + update_at = models.DateField(auto_now=True) + + class Meta: + ordering = ['-update_at', '-create_at'] + indexes = [ + models.Index(fields=['id', 'slug']), + models.Index(fields=['title']), + models.Index(fields=['-update_at', '-create_at']) + ] + + def save(self, *args, **kwargs): + + # Save the slug with the title input parameter + if not self.slug or self.slug != self.title: + self.slug = slugify(self.title, allow_unicode=True) + super(Product, self).save(*args, **kwargs) + + def __str__(self): + return self.title + + +class Category(models.Model): + ''' + This class is for sorting and categorizing products. + ''' + + # initial fields + label = models.CharField(max_length=200, unique=True, validators=[english_character_regex]) + slug = models.SlugField(max_length=200, unique=True) + + # relationship with other models + owner = models.ForeignKey(User, on_delete=models.CASCADE) + + class Meta: + ordering = ['label'] + indexes = [ + models.Index(fields=['label']) + ] + verbose_name = 'category' + verbose_name_plural = 'categories' + + def save(self, *args, **kwargs): + + # Save the slug with the label input parameter + if not self.slug or self.slug != self.label: + self.slug = slugify(self.label, allow_unicode=True) + super(Category, self).save(*args, **kwargs) + + def __str__(self): + return self.label diff --git a/utils/validator.py b/utils/validator.py new file mode 100644 index 0000000..b43707a --- /dev/null +++ b/utils/validator.py @@ -0,0 +1,6 @@ +from django.core.validators import RegexValidator + +english_character_regex = RegexValidator( + regex=r'^[a-zA-Z0-9\s\-_\.!@#\$%^&*()+=\[\]{};:,<>\?/\\]{2,200}$', + message='Only English letters, numbers, and spaces are allowed, and the allowed characters are between 2 and 200', +)