继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Django模型字段的10个冷门技巧,让你的代码更高效!

HUWWW
关注TA
已关注
手记 305
粉丝 37
获赞 133

1. 使用 clean() 自定义字段验证方法

你知道可以用 clean() 方法为特定的字段添加自定义的验证逻辑吗?

    from django.db import models  
    from django.core.exceptions import ValidationError  

    class Product(models.Model):  
        name = models.CharField(max_length=100)  
        price = models.DecimalField(max_digits=10, decimal_places=2)  
    def clean(self):  
        if self.price <= 0:  
           raise ValidationError("价格必须大于零哦。")

在你的保存逻辑或表单中使用 clean() 来确保无效数据不会混入你的数据库。

2. 条件性默认值

有时候,你可能需要一些默认值根据特定条件来动态调整。

从 django.utils.timezone 导入 now

class Event(models.Model):
    name = models.CharField(max_length=100)
    start_date = models.DateTimeField(default=now)
    end_date = models.DateTimeField(default=lambda: now() + timedelta(days=7))

这非常棒,适用于时间戳或自动生成默认未来日期。

3. 多字段唯一性约束,例如,确保邮箱地址和电话号码组合的唯一性。

用唯一性约束替换不再推荐使用的 unique_together 约束,以便更好地控制。

from django.db import models  

# 定义了一个名为`Membership`的模型类
class Membership(models.Model):  
    # 定义了一个名为`user`的外键字段,关联到`auth.User`,并设置删除时级联删除
    user = models.ForeignKey('auth.User', on_delete=models.CASCADE)  
    # 定义了一个名为`group`的外键字段,关联到`Group`,并设置删除时级联删除
    group = models.ForeignKey('Group', on_delete=models.CASCADE)  

    class Meta:  
        # 定义了模型的约束条件
        constraints = [  
            # 定义了一个唯一约束条件,字段为`user`和`group`,命名为`唯一会员关系`
            models.UniqueConstraint(fields=['user', 'group'], name='唯一会员关系')  
        ]

这确保了,没有用户被添加到相同的组重复。

4. 在枚举中使用choices

Django的choices使字段更加整洁有序,特别是在使用枚举时。

    from django.db import models  

    class 请求状态(models.TextChoices):  
        待处理 = 'P', '待处理'  
        已批准 = 'A', '已批准'  
        已拒绝 = 'R', '已拒绝'  

    class 请求(models.Model):  
        状态 = models.CharField(max_length=1, choices=请求状态.choices, default=请求状态.待处理)

使用类似 Status.PENDING 而不是直接使用字符串。

5. 用于多对多的定制,就像这样

需要在多对多关系中加入额外数据吗?可以使用 through

    class Author(models.Model):  
        name = models.CharField(max_length=100)  

    class Book(models.Model):  
        title = models.CharField(max_length=100)  
        authors = models.ManyToManyField(Author, through='Authorship')  

    class Authorship(models.Model):  
        author = models.ForeignKey(Author, on_delete=models.CASCADE)  
        book = models.ForeignKey(Book, on_delete=models.CASCADE)  
        role = models.CharField(max_length=50)  # 例如:合著者,编辑。

这让你可以了解更多关于关系的细节。

6. 字段级别的可编辑性与 editable=False

禁止管理员直接编辑,但仍允许通过程序更新。

定义了一个名为Order的类,它继承了models.Model。其中total_price是一个小数字段,最大位数为10,小数点后有2位,且该字段不允许编辑。

你仍然能在代码里更新 total_price,但在后台不能更新。

7.: 自定义文件上传位置

使用 upload_to 动态整理上传文件。

    def 上传头像(instance, filename):  
        return f"uploads/{instance.user.id}/{filename}"  

    class 用户资料(models.Model):  
        user = models.OneToOneField('auth.User', on_delete=models.CASCADE)  
        头像 = models.ImageField(upload_to=上传头像)

上传的文件会根据用户的ID整齐存储起来。

8. 在模型中使用 Property 字段

Django框架中的模型可以包含计算字段。

员工类定义了一个名为 Employee 的模型类。

该类包含两个属性:first_name 和 last_name,分别表示员工的名字和姓氏,每个属性都是长度最多为50个字符的字符串。

此外,该类还定义了一个名为 full_name 的属性方法,用于返回员工的全名,即名字和姓氏的组合。

像访问字段一样访问它:employee.full_name

9. 自动设置字段的 save() 方法

通过重写 save() 方法来自定义字段的保存行为。

    # 定义一个名为Article的模型类
    class Article(models.Model):  
        # 定义一个名为title的CharField,最大长度为100
        title = models.CharField(max_length=100)  
        # 定义一个名为slug的SlugField,唯一且可为空
        slug = models.SlugField(unique=True, blank=True)  

        # 重写保存方法,自定义slug的生成逻辑
        def save(self, *args, **kwargs):  
            # 如果slug为空,则根据title生成slug
            if not self.slug:  
                # 将title转为小写并替换空格为破折号
                self.slug = self.title.lower().replace(' ', '-')  
            # 调用父类的save方法
            super().save(*args, **kwargs)

如果没有提供网址别名,则根据标题自动生成。

10. 软删除 with is_archived

与其删除记录,不如存档。

# 抽象基类,定义基础模型
class BaseModel(models.Model):  
    is_archived = models.BooleanField(default=False)  

    # 重写删除方法,标记为已归档,而不是真正删除
    def delete(self, *args, **kwargs):  
        self.is_archived = True  
        self.save()  

    class Meta:  
        # 设置为抽象类,不能实例化
        abstract = True

您的数据在用户看来已被删除的情况下仍然保持安全。

结论:
Django的模型系统非常强大,这些技巧可以帮助你更好地利用它,写出更简洁、更高效的代码。你已经在用哪些技巧了呢?你最喜欢哪个呢?

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP