Django Model Best Practices: 编写高质量的模型代码
- 为模型类指定verbose_name和verbose_name_plural属性,以提高代码可读性。
class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() class Meta: verbose_name = '文章' verbose_name_plural = verbose_name
- 将字符串常量定义为类属性,以提高代码可读性和重用性。
class Article(models.Model): STATUS_DRAFT = 'draft' STATUS_PUBLISHED = 'published' STATUS_CHOICES = [ (STATUS_DRAFT, '草稿'), (STATUS_PUBLISHED, '已发布') ] status = models.CharField(max_length=10, choices=STATUS_CHOICES, default=STATUS_DRAFT)
- 如果需要在模型中使用url,建议使用reverse()函数来生成url,以避免硬编码。
from django.urls import reverse class Article(models.Model): title = models.CharField(max_length=200) def get_absolute_url(self): return reverse('article_detail', kwargs={'pk': self.pk})
- 使用ForeignKey来建立模型之间的关系,使用related_name属性来避免名称冲突。
class Author(models.Model): name = models.CharField(max_length=100) class Article(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='articles')
- 将复杂的查询封装到模型的管理器中,以提高代码可读性和重用性。
class ArticleQuerySet(models.QuerySet): def published(self): return self.filter(status='published') class ArticleManager(models.Manager): def get_queryset(self): return ArticleQuerySet(self.model, using=self._db) def published(self): return self.get_queryset().published() class Article(models.Model): title = models.CharField(max_length=200) status = models.CharField(max_length=10, choices=STATUS_CHOICES, default=STATUS_DRAFT) objects = ArticleManager()
- 使用signals来处理模型的业务逻辑,以将业务逻辑从视图和表单中抽离出来。
from django.db.models.signals import pre_save from django.dispatch import receiver from django.utils.text import slugify class Article(models.Model): title = models.CharField(max_length=200) slug = models.SlugField(unique=True) @receiver(pre_save, sender=Article) def generate_slug(sender, instance, **kwargs): if not instance.slug: instance.slug = slugify(instance.title)
- 使用abstract base class来避免代码重复。
class TimestampedModel(models.Model): created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: abstract = True class Article(TimestampedModel): title = models.CharField(max_length=200) content = models.TextField()
相关文章