本文主要内容是关于Django框架中models的知识小结
Python3.7.3
Django==2.0.7
一对多 : fk字段在"多"的models中定义
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(
Blog,
on_delete=models.CASCADE,
related_name="entryblogs",
related_query_name="entryqueryblogs"
)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self):
return self.headline
models.ForeignKey(to,on_delete,** options)
# to : 关联的类(必填)
# on_delete : 与"关联表"的关系(必填)
models.ForeignKey(to='self', on_delete=models.CASCADE)
on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE, # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做
on_delete=models.PROTECT, # 删除关联数据,引发错误ProtectedError
# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET, # 删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
在生成数据库时,Django追加"_id"字段名称来创建其数据库列名,可以通过指定显式更改此内容db_column
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
# ...
class Entry(models.Model):
blog = models.ForeignKey(
Blog,
on_delete=models.CASCADE,
related_name="entryblogs",
)
# ...
由存放外键的表(Entry)->查->被关联的表(Blog)
>>> e = models.Entry.objects.get(id=1)
>>> e.blog
<Blog: haha>
由被关联的表(Blog)->查->存放外键的表(Entry)
>>> b = models.Blog.objects.get(id=1)
>>> b.entryblogs
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x10d58c908>
>>> b.entryblogs.all() # 一对多,所以反向获取到的数据是一个多条数据,需要all()
<QuerySet [<Entry: 1>]>
>>> b = models.Blog.objects.get(id=1)
>>> models.Entry.objects.filter(blog=b).filter(headline=1)
<QuerySet [<Entry: 1>]>
>>> models.Blog.objects.filter(id=1).filter(entryqueryblogs__headline=1)
<QuerySet [<Blog: haha>]>
ManyToManyField(to,**options)
MtoM字段根据需求可以放到两个有关联的表中的任意一个
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
# ...
class Entry(models.Model):
authors = models.ManyToManyField(Author)
# ...
OneToOneField(to,on_delete,parent_link = False,** options)
class Entry(models.Model):
blog = models.ForeignKey(
Blog,
on_delete=models.CASCADE,
related_name="entryblogs",
related_query_name="entryqueryblogs"
)
# ...
class Meta:
pass
class Entry(models.Model):
blog = models.ForeignKey(
Blog,
on_delete=models.CASCADE,
related_name="entryblogs",
related_query_name="entryqueryblogs"
)
class Meta:
db_table = "app名_Entry"
# app名+类名(个人喜好,根据项目中遇到的坑,我建议表名应该为:小写app名+小写的类名)
目前通过做过的这些项目,这个功能感觉有点鸡肋,具体怎么用还是要说一下
class Entry(models.Model):
blog = models.ForeignKey(
Blog,
on_delete=models.CASCADE,
related_name="entryblogs",
related_query_name="entryqueryblogs"
)
# ...
class Meta:
order_with_respect_to = 'blog' # fk字段名
>>> b = models.Blog.objects.get(id=1)
>>> b
<Blog: haha>
>>> b.get_entry_order()
<QuerySet [1, 2]> # 里面存放的仅仅是int类型的数据,并不是obj
拿到的仅仅是一个由id组成的列表,并不是我们想要的queryset数据
# 拿到被关联的obj数据
b = models.Blog.objects.get(id=1)
# obj.get_小写关联的表名_order()
b.get_entry_order()
给定的字段,加起来在表中保持唯一值
class Entry(models.Model):
body_text = models.TextField()
pub_date = models.DateField()
# ...
class Meta:
unique_together = (("body_text", "pub_date"),)