创建模型类
字段类型
在对应app下的models.py中定义模型类
django 字段类型参考: django field types
models.py:
from django.db import models
# Create your models here.
class Product(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
price = models.DecimalField(max_digits=6, decimal_places=2)
inventory = models.IntegerField()
last_update = models.DateTimeField(auto_now=True)
主键
id是自动创建的,且为主键。
如果不想自动创建ID主键,可以自定义一个主键:
sku = models.CharField(max_length=10, primary_key=True)
选项
class Product(models.Model):
MEMBERSHIP_CHOICES = [
('B', 'Bronze'),
('C', 'Silver'),
('G', 'Gold')
]
membership = models.CharField(max_length=1, choices=MEMBERSHIP_CHOICES, default='B')
一对一关联
在子模型中定义 models.OneToOneField
- on_delete=models.CACSCADE:
当删除Customer时,关联的的Address也删除
-
on_delete=models.SET_NULL:
当删除Customer时,关联的Address中的customer字段设置为NULL
-
on_delete=models.SET_DEFUALT:
当删除Customer时,关联的Address中的customer字段设置为其默认值
-
on_delete=models.PROTECT
当有关联的Address时,阻止删除customer
设置primary_key=True限制一个customer只有一个address
class Address(models.Model):
street = models.CharField(max_length=255)
city = models.CharField(max_length=255)
# django会自动创建反向关联,所以不需要在Customer中定义address字段了
customer = models.OneToOneField(Customer, on_delete=models.CASCADE, primary_key=True)
一对多关联
class Address(models.Model):
street = models.CharField(max_length=255)
city = models.CharField(max_length=255)
# 一个customer有多个Address
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
多对多关联
class Promotion(models.Model):
"""产品促销"""
description = models.CharField(max_length=255)
discount = models.FloatField()
# product_set字段是默认创建的
class Product(models.Model):
# 多对多
promotions = models.ManyToManyField(Promotion)
# django会自动在Promotion类中创建反向关联,如Promotion中默认字段名:product_set,如果要改变默认的关联名,设置related_name参数
# promotions = models.ManyToManyField(Promotion, related_name='products')
解决循环依赖
两个类互相依赖的情况:
Collection Model中的featured_product依赖Product Model ,但Product中的collection又依赖了Collection,依赖的模型必须定义在前面,如果相互依赖,向上面这种情况,就会报未定义错误:
解决方法:
class Collection(models.Model):
title = models.CharField(max_length=255)
featured_product = models.ForeignKey('Product', on_delete=models.SET_NULL, null=True, related_name='featured_product')
通用关系
如product、image、video都有对应的tag,所有tag可以单独提出来,做一个标签库。
tags/models.py
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
# Create your models here.
class Tag(models.Model):
label = models.CharField(max_length=255)
class TaggedItem(models.Model):
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
# 通用关系:product/images/videos...
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
# 对应的ID
object_id = models.PositiveIntegerField()
# 具体对象
content_object = GenericForeignKey()