Refactor email system and add contact form backend
Refactored email sending to use a single HTML template with a base layout, removed plain text email templates, and updated all related backend logic. Introduced a new ContactMe model, serializer, Celery task, and API endpoints for handling contact form submissions, including email notifications. Renamed ShopConfiguration to SiteConfiguration throughout the backend for consistency. Updated frontend to remove unused components, add a new Services section, and adjust navigation and contact form integration.
This commit is contained in:
@@ -6,14 +6,13 @@ class ConfigurationConfig(AppConfig):
|
||||
name = 'configuration'
|
||||
|
||||
def ready(self):
|
||||
"""Ensure the ShopConfiguration singleton exists at startup.
|
||||
|
||||
"""Ensure the SiteConfiguration singleton exists at startup.
|
||||
Wrapped in broad DB error handling so that commands like
|
||||
makemigrations/migrate don't fail when the table does not yet exist.
|
||||
"""
|
||||
try:
|
||||
from .models import ShopConfiguration # local import to avoid premature app registry access
|
||||
ShopConfiguration.get_solo() # creates if missing
|
||||
from .models import SiteConfiguration # local import to avoid premature app registry access
|
||||
SiteConfiguration.get_solo() # creates if missing
|
||||
|
||||
except (OperationalError, ProgrammingError):
|
||||
# DB not ready (e.g., before initial migrate); ignore silently
|
||||
|
||||
@@ -2,7 +2,7 @@ from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class ShopConfiguration(models.Model):
|
||||
class SiteConfiguration(models.Model):
|
||||
name = models.CharField(max_length=100, default="Shop name", unique=True)
|
||||
|
||||
logo = models.ImageField(upload_to='shop_logos/', blank=True, null=True)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from rest_framework import serializers
|
||||
from .models import ShopConfiguration
|
||||
from .models import SiteConfiguration
|
||||
|
||||
|
||||
class ShopConfigurationAdminSerializer(serializers.ModelSerializer):
|
||||
class SiteConfigurationAdminSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ShopConfiguration
|
||||
model = SiteConfiguration
|
||||
fields = [
|
||||
"id",
|
||||
"name",
|
||||
@@ -29,9 +29,9 @@ class ShopConfigurationAdminSerializer(serializers.ModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class ShopConfigurationPublicSerializer(serializers.ModelSerializer):
|
||||
class SiteConfigurationPublicSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ShopConfiguration
|
||||
model = SiteConfiguration
|
||||
# Expose only non-sensitive fields
|
||||
fields = [
|
||||
"id",
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from .views import ShopConfigurationAdminViewSet, ShopConfigurationPublicViewSet
|
||||
from .views import SiteConfigurationAdminViewSet, SiteConfigurationPublicViewSet
|
||||
|
||||
router = DefaultRouter()
|
||||
router.register(r"admin/shop-configuration", ShopConfigurationAdminViewSet, basename="shop-config-admin")
|
||||
router.register(r"public/shop-configuration", ShopConfigurationPublicViewSet, basename="shop-config-public")
|
||||
|
||||
router.register(r"admin/shop-configuration", SiteConfigurationAdminViewSet, basename="shop-config-admin")
|
||||
router.register(r"public/shop-configuration", SiteConfigurationPublicViewSet, basename="shop-config-public")
|
||||
urlpatterns = router.urls
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
from rest_framework import viewsets, mixins
|
||||
from rest_framework.permissions import IsAdminUser, AllowAny
|
||||
from .models import ShopConfiguration
|
||||
from .models import SiteConfiguration
|
||||
from .serializers import (
|
||||
ShopConfigurationAdminSerializer,
|
||||
ShopConfigurationPublicSerializer,
|
||||
SiteConfigurationAdminSerializer,
|
||||
SiteConfigurationPublicSerializer,
|
||||
)
|
||||
|
||||
|
||||
class _SingletonQuerysetMixin:
|
||||
def get_queryset(self):
|
||||
return ShopConfiguration.objects.filter(pk=1)
|
||||
return SiteConfiguration.objects.filter(pk=1)
|
||||
|
||||
def get_object(self):
|
||||
return ShopConfiguration.get_solo()
|
||||
return SiteConfiguration.get_solo()
|
||||
|
||||
|
||||
class ShopConfigurationAdminViewSet(_SingletonQuerysetMixin, viewsets.ModelViewSet):
|
||||
class SiteConfigurationAdminViewSet(_SingletonQuerysetMixin, viewsets.ModelViewSet):
|
||||
permission_classes = [IsAdminUser]
|
||||
serializer_class = ShopConfigurationAdminSerializer
|
||||
serializer_class = SiteConfigurationAdminSerializer
|
||||
|
||||
|
||||
class ShopConfigurationPublicViewSet(_SingletonQuerysetMixin, viewsets.ReadOnlyModelViewSet):
|
||||
class SiteConfigurationPublicViewSet(_SingletonQuerysetMixin, viewsets.ReadOnlyModelViewSet):
|
||||
permission_classes = [AllowAny]
|
||||
serializer_class = ShopConfigurationPublicSerializer
|
||||
serializer_class = SiteConfigurationPublicSerializer
|
||||
Reference in New Issue
Block a user