简单介绍如何建立Django模型。
python manage.py startapp app01
①模型字段
假设定义一个文章模型数据表吧。
无非就是确定字段类型,确定参数可选项(字段名,是否为主键,最大字段长度,是否允许非空)等等,注意和其他表的字段建立外键约束情况。还有啥不同表之间创建一对一关系OneToOneFIeld,ManyToManyField等。
from django.db import models
from user.models import User
# app01/models.py
class Article(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(verbose_name="标题", max_length=100, null=False)
content = models.TextField(verbose_name="内容", null=False)
pub_date = models.DateTimeField(verbose_name="发布时间")
user = models.ForeignKey(User, on_delete=models.CASCADE)
on_delete=models.CASCADE,表示删除某一关联数据时,与之关联的所有数据都会被删除。还有models.SET_NULL,models.SET_DEFAULT等其他操作。除此之外,可选参数有related_name,requery_query_name等反向操作。
from django.db import models
# user/models.py
class User(models.Model):
id = models.AutoField(primary_key=True)
username = models.CharField('用户名', max_length=30,null=True,blank=True,unique=True)
password = models.CharField('密码', max_length=30)
email = models.EmailField('邮箱', null=True, blank=True, unique=True)
设置Meta元数据。设置表名(默认是应用名+类名作为表名),单复数名选项,排序规则等。
class User(models.Model):
...
class Meta:
db_table = 'article'
verbose_name = '文章信息'
verbose_name_plural = '文章信息'
ordering = ['-pub_date']
每次修改模板类记得在终端执行数据迁移操作
python manage.py makemigrations
python manage.py migrate
使用数据库管理软件查看迁移后生成的表信息,这里使用的是heidisql
②模型方法
定义Article类的实例方法,返回直观的文章发布时间。
from datetime import timezone, timedelta
...
class Article(models.Model):
...
class Meta:
...
def pub_date_status(self):
now = timezone.now()
if now - self.pub_date > timedelta(days=30):
return "30天前"
elif now - self.pub_date > timedelta(days=7):
return "7天前"
else:
return "最近"
定义Article类属性方法,返回文章标题和发布时间。
"""
@property 装饰器可以让方法以属性的方式被访问,
直接通过实例对象.属性名的方式来访问。
"""
@property
def article_detail(self):
return f"({self.title}, {self.pub_date})"
也可对已有的方法进行重写。
def save(self, *args, **kwargs):
if self.user.username == "GGBond":
return # GGBond不许发文章
else:
return super().save(*args, **kwargs)
③模型继承
抽象基类。User继承了BaseUser里的姓名和年龄字段,在BaseUser类的Meta类中添加属性 ‘abstract = True’,表明BaseUser类为抽象基类
class BaseUser(models.Model):
name = models.CharField('用户名', max_length=30,null=True,blank=True,unique=True)
age = models.IntegerField('年龄')
class Meta:
abstract = True
class User(BaseUser):
id = models.AutoField(primary_key=True)
password = models.CharField('密码', max_length=30)
email = models.EmailField('邮箱', null=True, blank=True, unique=True)
Meta继承。abstract=True不会被子类继承,也就是如果子类也想弄成抽象基类,需要显式调用。以及元数据属性db_table对抽象基类无效。
class BaseUser(models.Model):
name = models.CharField('用户名', max_length=30,null=True,blank=True,unique=True)
age = models.IntegerField('年龄')
class Meta:
abstract = True
ordering = ['age']
class User(BaseUser):
id = models.AutoField(primary_key=True)
password = models.CharField('密码', max_length=30)
email = models.EmailField('邮箱', null=True, blank=True, unique=True)
class Meta(BaseUser.Meta):
db_table = 'author'
# 也可以显式不继承
ordering = []
还有多表继承,代理模型等操作。