manyTomany
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self): # __unicode__ on Python 2
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self): # __unicode__ on Python 2
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
... date_joined=date(1962, 8, 16),
... invite_reason="Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
[<Person: Ringo Starr>]
>>> ringo.group_set.all().order_by('membership__date_joined')
[<Group: The Beatles>]
>>> Group.objects.filter(members__name__startswith='Paul')
[<Group: The Beatles>]
>>> Person.objects.filter(
... group__name='The Beatles',
... membership__date_joined__gt=date(1961,1,1))
[<Person: Ringo Starr]
ringos_membership = ringo.membership_set.get(group=beatles)
oneTomany
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self): # __unicode__ on Python 2
return self.name
class Author(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
def __str__(self): # __unicode__ on Python 2
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog)
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): # __unicode__ on Python 2
return self.headline
>>> Entry.objects.filter(blog__name='Beatles Blog')
还可以反向工作。若要引用一个“反向”的关系,只需要使用该模型的小写的名称。
>>> Blog.objects.filter(entry__headline__contains='Lennon')
继承
- 抽象基类: 这个model 不创建任何数据表,它的字段被加入子类中
- 多表继承: 每个model 有专属的数据表,父类和子类通过oneToone来实现
- 代理继承: 所有model 使用同一张表,每个model 可以添加不同的python 行为。
get vs filter
- django 的 get 方法是从数据库的取得一个匹配的结果,返回一个对象,如果记录不存在的话,它会报错。
- django 的 filter 方法是从数据库取得匹配的结果,返回一个对象列表,如果记录不存在的话,它会返回 []。
- 待验证
filter 好像有缓存数据的功能,第一次查询数据库并生成缓存,下次再调用 filter 方法的话,直接取得缓存的数据,而 get 方法每次执行都是直接查询数据库的
null vs blank
在 python 检查中 blank = [None, '', [], {}, ()] 所以设置 null = True 必须blank = True
但是正常的save 是没有去验证这个blank 所以无论什么值都无所谓,如果需要验证blank 可以手动调用model.field_clean 或者full_clean.
如果需要验证 null = True , blank = False , 那么可以自己写clean 函数去验证字段,但是model 定义中还是需要写成null = True , blank = True
- blank 为空字符串 默认 false
- null 为null 默认 false
values_list vs values
- values 返回字典
- values_list 返回元组
<code>
Entry.objects.values_list('id', 'headline')
[(1, 'First entry'), ...]
Entry.objects.values_list('id', flat=True)
[1,2,3]
Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]
<code>