Django Model Best Practices: 编写高质量的模型代码

2023-04-06 00:00:00 模型 编写 高质量
  1. 为模型类指定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
  1. 将字符串常量定义为类属性,以提高代码可读性和重用性。
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)
  1. 如果需要在模型中使用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})
  1. 使用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')
  1. 将复杂的查询封装到模型的管理器中,以提高代码可读性和重用性。
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()
  1. 使用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)
  1. 使用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()

相关文章