咨询:为Django电商搭建的这些模型是否配置正确?
核查Django电商系统模型代码配置问题
以下是针对你提供的Django电商模型代码的问题核查及修正建议:
1. 分类选项格式错误
CATGORIES_CHOICE(注意拼写错误,应为CATEGORIES_CHOICE)的格式不符合Django choices要求,Django要求每个选项是二元组(存储值,显示文本),当前单元素元组会导致报错。
修正后:
CATEGORIES_CHOICE = ( ("Sports", "运动用品"), ("Fashion", "时尚服饰"), ("Electronics", "电子产品"), ("Fishing", "户外垂钓"), ("Books", "图书音像"), ("Cosmetics", "美妆护肤"), ("Games", "游戏娱乐"), ("Pets", "宠物用品"), ("Outwear", "户外服饰"), ("Lingerie", "内衣家居"), ("Medicals", "医疗健康") )
2. 用户模型设计问题
- 直接存储明文密码严重不安全,Django自带用户认证系统,建议继承
AbstractUser或AbstractBaseUser,并使用Django的密码哈希机制。 - 密码字段长度
max_length=15过短,哈希后的密码长度通常超过15位,应设置为128。
修正后示例:
from django.contrib.auth.models import AbstractUser class User(AbstractUser): phone_number = PhoneNumberField(region="US") address1 = models.TextField() address2 = models.TextField(blank=True, null=True) created = models.DateTimeField(auto_now_add=True) # 取消原有的email、password字段,AbstractUser已包含这些字段且自带哈希处理
3. 商品模型字段问题
store_id字段名不符合Django规范,ForeignKey会自动生成_id后缀,建议改为store;category和condition的choices参数为空,需关联定义好的选项,同时condition需补充对应的选项集合;discount字段max_digits=2限制过大,若按百分比计算(如30%=0.30),建议设置max_digits=3以支持100%(1.00)的折扣;sales_price属性返回字符串且使用float运算,存在精度损失,应返回Decimal类型。
修正后片段:
# 先补充condition的选项 PRODUCT_CONDITION_CHOICE = ( ("New", "全新"), ("Used", "二手"), ("Refurbished", "翻新") ) class Product(models.Model): store = models.ForeignKey(Store, on_delete=models.CASCADE, related_name="products") title = models.CharField(max_length=110) description = models.TextField(null=True, blank=True) price = models.DecimalField(max_digits=15, decimal_places=2) discount = models.DecimalField(max_digits=3, decimal_places=2, default=0.00) available = models.IntegerField() category = models.CharField(choices=CATEGORIES_CHOICE, max_length=20) condition = models.CharField(choices=PRODUCT_CONDITION_CHOICE, max_length=20) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) @property def sales_price(self): if self.discount > 1: # 若折扣按百分比传入(如30代表30%),需先转换为小数 discount_rate = self.discount / 100 else: discount_rate = self.discount return self.price * (1 - discount_rate)
4. 购物车模型问题
ordered_date字段未设置允许为空,当ordered=False时该字段无值,会导致数据库报错,需添加null=True, blank=True;order_number默认值设为7会导致重复,建议使用UUIDField自动生成唯一订单号;Cart与CartItem的关联逻辑不合理,通常购物车和商品的关联应通过CartItem指向Cart实现。
修正后片段:
import uuid class CartItem(models.Model): cart = models.ForeignKey(Cart, on_delete=models.CASCADE, related_name="items") item = models.ForeignKey(Product, on_delete=models.CASCADE) quantity = models.PositiveIntegerField(default=1) class Cart(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="carts") order_number = models.UUIDField(unique=True, default=uuid.uuid4, editable=False) ordered = models.BooleanField(default=False) created_date = models.DateTimeField(auto_now_add=True) ordered_date = models.DateTimeField(null=True, blank=True)
5. 评论模型问题
product_id使用ManyToManyField不合理,单条评论应对应单个商品,改为ForeignKey;ManyToManyField不支持on_delete参数,会直接报错。
修正后:
class Review(models.Model): created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="reviews") product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="reviews") rating = models.DecimalField(max_digits=2, decimal_places=1, default=0.0) label = models.CharField(max_length=100) comment = models.TextField(max_length=500) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True)
6. 其他模型缩进与选项问题
Saved和History模型的字段缩进错误,需缩进至类内部;ORDER_HISTORY_CHOICE为空,History的status字段需补充订单状态选项。
修正后:
ORDER_HISTORY_CHOICE = ( ("Pending", "待处理"), ("Shipped", "已发货"), ("Delivered", "已送达"), ("Cancelled", "已取消") ) class Saved(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="saved_products") products = models.ManyToManyField(Product) class History(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="order_history") products = models.ManyToManyField(Product) status = models.CharField(choices=ORDER_HISTORY_CHOICE, max_length=20)
内容的提问来源于stack exchange,提问作者samad aderinto
相关产品推荐
相关产品推荐

