from django.db import models
#博客文章表
class Article(models.Model):
title = models.CharField(max_length=20)
body = models.TextField()
createtime = models.DateField(auto_now_add=True)
#类别,外键关联Category表 多对多关系 默认会新增一张表记录多对多关系 名字为该表_关联表
category = models.ManyToManyField(to='Category')
#作者,一对多关系 将外键删除时,阻止 删除操作,抛出ProtectedError异常
author = models.ForeignKey(to='Author',on_delete=models.PROTECT)
class Meta:
db_table = 'article'
ordering = ['-createtime']
def __str__(self):
return self.title
#类别表
class Category(models.Model):
name = models.CharField(max_length=20)
class Meta:
db_table ='category'
def __str__(self):
return self.name
#作者表
class Author(models.Model):
name = models.CharField(max_length=20)
gender=(
('男','M'),('女','F'),
)
sex = models.CharField(choices=gender,max_length=20)
class Meta:
db_table = 'author'
def __str__(self):
return self.name
#账户表
class Account(models.Model):
user = models.OneToOneField(to='Author',on_delete=models.CASCADE)
balance = models.FloatField(max_length=50)
class Meta:
db_table = 'account'
def __str__(self):
return self.user
增
方式1:
Author.objects.create(name='张三',sex='男')
方式2:
>>> author = Author(2,'李四','M')
>>> author.save()
或者
>>> author = Author(name='王五',sex='F')
>>> author.save()
查询数据库如图:
SELECT * FROM author
有关联对象下的数据新增
一对一:
方式1:传入各个字段
>>> account = Account.objects.create(user_id=1,balance=100.0)
方式2:传入模型实例
>>> account = Account(user=author,balance=200.0)
>>> account.save()
查询数据库:
SELECT * FROM account
一对多:
为了测试方便,先新增一个类别表的数据
Category.objects.create(name='体育')
Category.objects.create(name='传记')
方式1:传入各个字段,这里一对多的字段为作者,在表中存放的是author_id字段,这里可以直接传入
>>> Article.objects.create(title='标题1',body='文章的内容',author_id=1)
方式2:传入模型实例
>>> author = Author.objects.get(name='张三')
>>> Article.objects.create(title='标题2',body='222',author=author)
这时候查看数据库: select * from article,这里是没有category字段,因为在多对多关系字段,会自动生成第三张表处理多对多关系(也可以自定义表的内容)
多对多:
接上述,刚刚新建的两条测试数据都没有分类字段,这里的category字段在表结构也不是直接存储在article表中,是存在自动生成的第三张表,如图:
新增多对多关系
方式1:通过从表进行关联
直接传入category的主键id
>>> article1 = Article.objects.get(id=1)
>>> article1
<Article: 标题1>
>>> article1.category.add(1)
或者直接传入一个模型实例也可以
>>> article1 = Article.objects.get(id=1)
>>> category = Category.objects.get(name='传记')
>>> article1.category.add(category)
查询数据库 select * from article_category
方式2:通过主表进行关联
直接传入article的主键id
>>> category = Category.objects.get(name='传记')
>>> category.article_set.add(2)
或者直接传入一个模型实例也可以
>>> category = Category.objects.get(name='体育')
>>> article = Article.objects.get(id=2)
>>> category.article_set.add(article)
查询数据库 select * from article_category
删
删除没有关联的数据
obj = XX.objects.get()
obj.delete()
删除外键关联的数据
1.删除账户表中的数据(一对一)
>>> account = Account.objects.get(user_id=1)
>>> account.delete()
查看数据库中用户id为1的账户信息已经删除,但是id=1的author并没有删除
2.删除author表中的数据
>>> author = Author.objects.get(id=2)
>>> author.delete()
这时候查看数据库中,不仅id=2的author被删除了,同时account表中的user_id=2的账户也删除了
这里就要说明字段: on_delete = modles.CASCADE字段的意思了,表示如果该外键数据删除,该数据也同时删除
还有一些典型的配置 比如:
PROTECT:阻止删除操作,抛出ProtectedError异常
SET_NULL:将外键字段设为null,只有当字段设置了null=True时,方可使用该值。
SET_DEFAULT:将外键字段设为默认值。只有当字段设置了default参数时,方可使用。
SET():设置为一个传递给SET()的值或者一个回调函数的返回值。注意大小写。
3.这里删除一对多关系
查看到Article模型有字段
author = models.ForeignKey(to='Author',on_delete=models.PROTECT)
删除一个Article
>>> article = Article.objects.get(id=1)
>>> article.delete()
这时候查看数据表,arctile表中的id=1的数据已经删除
然后尝试删除外键关联字段的表数据
>>> author = Author.objects.get(id=1)
>>> author.delete()
会抛出异常
django.db.models.deletion.ProtectedError: ("Cannot delete some instances of model 'Author' because they are referenced through a protected foreign key: 'Article.author'", <QuerySet [<Article: 标题2>]>)
4.删除多对多关系
上述的操作中,我们已经删除了article表中id=1的数据
这时候查看数据库中对多对关系表article_category中的数据
这里已经没有了article_id=1的所有数据,表示这两张表删除互不影响,但是第三张的管理表一定级联删除
5.批量删除
删除所有Article表中的数据
>>> Article.objects.all().delete()
(3, {'modelsshare.Article_category': 2, 'modelsshare.Article': 1})