在Django中,规则继承是一种强大的机制,它允许你在模型和表单中重用和扩展验证逻辑。以下是如何在模型和表单中使用Django规则继承的基础概念、优势、类型、应用场景以及示例代码。
规则继承是指在一个类中定义一组验证规则,然后在其他类中继承这些规则,以便重用和扩展。这有助于减少代码重复,并使验证逻辑更加模块化和可维护。
假设我们有一个基础模型BaseModel
,其中包含一些通用的验证规则:
from django.db import models
from django.core.validators import MinLengthValidator, RegexValidator
class BaseModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
def clean(self):
super().clean()
# 通用验证逻辑
if hasattr(self, 'name'):
self.name = self.name.strip()
if len(self.name) < 3:
raise ValidationError({'name': 'Name must be at least 3 characters long.'})
class Product(BaseModel):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.IntegerField(validators=[MinLengthValidator(0)])
def clean(self):
super().clean()
# 特定于Product的验证逻辑
if self.price < 0:
raise ValidationError({'price': 'Price cannot be negative.'})
假设我们有一个基础表单BaseForm
,其中包含一些通用的验证规则:
from django import forms
from django.core.validators import MinLengthValidator, RegexValidator
class BaseForm(forms.Form):
def clean(self):
cleaned_data = super().clean()
# 通用验证逻辑
for field_name, field in self.fields.items():
if hasattr(field, 'validators'):
for validator in field.validators:
if isinstance(validator, MinLengthValidator):
value = cleaned_data.get(field_name)
if value and len(value) < validator.limit_value:
self.add_error(field_name, f'{field_name.capitalize()} must be at least {validator.limit_value} characters long.')
return cleaned_data
class ProductForm(BaseForm):
name = forms.CharField(max_length=100)
price = forms.DecimalField(max_digits=10, decimal_places=2)
stock = forms.IntegerField(validators=[MinLengthValidator(0)])
def clean(self):
cleaned_data = super().clean()
# 特定于ProductForm的验证逻辑
price = cleaned_data.get('price')
if price and price < 0:
self.add_error('price', 'Price cannot be negative.')
return cleaned_data
问题:为什么在继承的模型或表单中添加新的验证规则时,原有的验证规则没有被执行?
原因:可能是因为在子类的clean
方法中没有正确调用父类的clean
方法。
解决方法:确保在子类的clean
方法中使用super().clean()
来调用父类的clean
方法。
class Product(BaseModel):
# 字段定义
def clean(self):
super().clean() # 确保调用父类的clean方法
# 特定于Product的验证逻辑
通过这种方式,你可以有效地在Django模型和表单中使用规则继承,从而提高代码的可重用性和可维护性。
领取专属 10元无门槛券
手把手带您无忧上云