这里是我自己整理的一些资料,大家不懂的可以相互学习呀。。。

Django Model 中的各项基础设置

Django ZZT 1931次浏览 已收录 0个评论

关联关系字段 (Relationship fields)

ForeignKey,ManyToManyField与OneToOneField分别在Model中定义多对一,多对多,一对一关系。
例如,一本书由一家出版社出版,一家出版社可以出版很多书。一本书由多个作者合写,一个作者可以写很多书。

class Author(models.Model):
    name=models.CharField(max_length=20)
class Publisher(models.Model):
    name=models.CharField(max_length=20)
class Book(models.Model):
    name=models.CharField(max_length=20)
    pub=models.ForeignKey(Publisher)
    authors=models.ManyToManyField(Author)

1.关联尚未定义的Model

如果你要与某个尚未定义的 model 建立关联 ,就使用 model 的名称,而不是使用 model 对象本身。

例子中,如果Publisher与Author在Book后面定义,需要写成下面的形式:

class Book(models.Model):
    name=models.CharField(max_length=20)
    pub=models.ForeignKey('Publisher')
    authors=models.ManyToManyField('Author')

2.Model关联自身

可以运用到无限极分类

class People(models.Model):
    name=models.CharField(max_length=20)
    leader=models.ForeignKey('self',blank=True,null=True)

Model也可以与自身做多对多关系

class Person(models.Model):
    friends = models.ManyToManyField("self")

默认情况下,这种关联关系是对称的,如果Person1是Person2的朋友,那么Person2也是Person1的朋友

p1=Person()
p1.save()
p2=Person()
p2.save()
p3=Person()
p3.save()
p1.friends.add(p2,p3)

上述情况下,要查找p3的朋友,不用p3.person_set.all(),而直接用p3.friends.all()就可以了

如果想取消这种对称关系,将symmetrical设为False

class Person2(models.Model):
    friends=(models.ManyToManyField("self",symmetrical=False)

这样查询p3的朋友,就需要p3.person_set.all()了

3.反向名称related_name

反向名称,用来从被关联字段指向关联字段。

注意,在你定义 抽象 model (abstract models) 时,你必须显式指定反向名称; 只有在你这么做了之后, 某些特别语法 (some special syntax) 才能正常使用。

class Book(models.Model):
    name=models.CharField(max_length=20)
    pub=models.ForeignKey(Publisher,related_name='pub')
    authors=models.ManyToManyField(Author,related_name='author')

这样用Publisher或者Author反向查询Book时可以用related_name了:publisher1.pub.all()或者author1.author.all()。

如果不想设置反向关系,设置related_name为'+'或者以'+'结束。

user = models.ForeignKey(User, related_name='+')

如果有多个ManyToManyField指向同一个Model,这样反向查询FOO_set的时候就无法弄清是哪个ManyToManyField字段了,可以禁止反向关系:

users = models.ManyToManyField(User, related_name='u+')
referents = models.ManyToManyField(User, related_name='ref+')

4.数据库表现 (Database Representation)

多对一:Django 使用ForeignKey字段名称+ "_id" 做为数据库中的列名称。在上面的例子中,BOOK model 对应的数据表中会有 一个 publisher_id 列。

你可以通过显式地指定 db_column 来改变该字段的列名称,不过,除非你想自定 义 SQL ,否则没必要更改数据库的列名称。

多对多:Django 创建一个中间表来表示ManyToManyField关系。默认情况下,中间表的名称由两个关系表名结合而成。

由于某些数据库对表名的长度有限制,所以中间表的名称会自动限制在64个字符以内,并包含一个不重复的哈希字符串。这

意味着,你可能看到类似 book_authors_9cdf4 这样的表名称。你可以使用 db_table 选项手动指定中间表名称。

但是,如果你想手动指定中间表,你可以用 through 选项来指定model 使用另外某个 model 来管理多对多关系。而这个 model 就是中间表所对应的 model :

class Person(models.Model):
    name = models.CharField(max_length=128)
    def __unicode__(self):
        return self.name
class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')
    def __unicode__(self):
        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)

这样,就可以记录某个person何时加入group了。

要建立Person与Group的关系就不能用add,create,remove了,而是需要通过Membership进行。


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()

clear()还是可以使用的

beatles.members.clear()

当多对多关系关联自身时,中间表的ForeignKey是可以指向同一个Model的,但是它们必须被看做ManyToManyField的两边,而不是对称的,需要设置 symmetrical=False。


乐趣公园 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Django Model 中的各项基础设置
喜欢 (1)

文章评论已关闭!