Django中ForeignKey和ManyToMany使用探究:

本文详细解析了 Django 模型中的 ForeignKey 和 ManyToManyField 的使用方法及应用场景,包括如何建立一对一、一对多及多对多的关系,并介绍了如何通过这些关系型字段进行数据查询。
摘要由CSDN通过智能技术生成

实验所用的models:

class Publication(models.Model):

name = models.CharField(max_length=64)

 

def to_dict(self):

return {'id': self.id, 'name': self.name}

 

def __str__(self):

return f'{self.name}'

 

 

class Person(models.Model):

name = models.CharField(max_length=64)

age = models.IntegerField()

 

def to_dict(self):

return {'id': self.id, 'name': self.name}

 

def __str__(self):

return f'{self.name}'

 

 

class Book(models.Model):

name = models.CharField(max_length=64)

author = models.ForeignKey(

Person,

null=True,

on_delete=models.CASCADE,

related_name='author_book',

)

# 暂时认为一本书对应的是一个出版商

publication = models.ForeignKey(

Publication,

null=True,

on_delete=models.CASCADE,

)

 

def to_dict(self):

return {'id': self.id, 'name': self.name}

 

def __str__(self):

return f'{self.name}'

 

 

class BookShop(models.Model):

name = models.CharField(max_length=64)

book = models.ManyToManyField(

Book,

related_name='book_bookshop',

)

person = models.ManyToManyField(

Person,

related_name='author_in_bookshop',

)

publication = models.ManyToManyField(

Publication,

)

 

def to_dict(self):

return {'id': self.id, 'name': self.name}

 

def __str__(self):

return f'{self.name}'

 

 

1.ForeignKey

在1:m的关系中会用到,都是一那一方作为外键。

比如 book:person 就是 m:1的关系

django中 要在book class中进行定义: author=models.ForeignKey(Person,related_name='book')

那么在mysql中生成数据表的时候就会看见:

Book表中会有author_id一列

 

使用:

books = Book.objects.all()

books.first().author

# 仔细想一下,这样查出来的author,应该是一个对象,因为是外键,这是一对多的关系

# 这里很明显是每一本书都对应一个author,所以不要用什么book.first().author.all()这样的东西,不对的。

 

另外我们再思考一下:

persons = Person.objects.all()

persons.first().author_book.all() 就可以双向查询了

2.ManyToMany

在n:m的关系中会用到,是双方互为对方的外键。

比如 book:bookshop 就是n:m的关系

这个在哪一方中定义 其实都是可以的

但是如果Book定义在BookShop之前,就应该在Bookshop之前进行定义

否则就会出现错误。

class BookShop(models.Model):

    book = models.ManyToManyField(

                           Book,

                            related_name='book_bookshop',

                    )

这样在mysql中会生成数据表:

book_bookshop表,表中会有id, bookshop_id,book_id三列

 

使用:

bookshops = BookShop.objects.all()

bookshops.first().person.all()

这个不用说了,由于多对多的关系,所以bookshop对应的肯定是多个person

同理啊

bookshops.first().book.all() 可以查询到第一家书店里面的所有书籍

 

我们也要思考一下这个问题:

persons = Person.objects.all()

persons.first().person_in_bookshop.all() 应该这样查

第一种定义多对多结构的方式:

class BookShop(models.Model):

    person = models.ManyToManyField(

        Person,

        related_name='author_in_bookshop',

    )

 

person.first().bookshop_set.all()   (x)    不可以这样使用的

应该这样用:persons.first().person_in_bookshop.all() 应该这样查

第二种定义多对多结构的方式:

class BookShop(models.Model):

    publication = models.ManyToManyField(

    Publication,

    )

 

publication = Publication.objects.first()

publication.bookshop_set.all() 就可以找到这家出版社 出版过的书所在的所有的书店了

 

但是为什么定义了related_name以后就不能使用modelname_set的原因我就不知道了

也许应该查一下manager相关的知识点,或许还得看一下源码。请知道的大佬告诉我一声.

 

说说这次简单实验的结论八:
    定义外键或者是多对多关系的时候最好不要使用related_name这个字段

    如果不定义的话就可以双向查找,如果定义了的话就...也许还有别的方法可以双向查找

    但目前我的知识而言不知道怎么查= =。

============================================================================

好了,这个结论是错的,是我一开始就把related_name的含义理解错了,所以就出现了这种问题。

而且去问老张,妈的又被他吐槽了,fuck,难受。

 

深夜吐槽系列:

    明天又是周一,又要上班了。上周五的时候因为这个多对多和外键,被老张吐槽个半死。

周五下班和另一个同事一起走的,结果得知他把俩人的工作一起全部做完了,心里一阵抽搐。

觉得自己好菜,本来想看文档的,但是看别人写的东西总是不如自己直接做来的记忆深刻。所以

熬了会儿夜,毕竟这个周末我又没看书,至少把这个 外键 和 多对多 搞清楚怎么用,是什么关系

搞懂了也算是...没白过了。

    而且周一我该开始弄爬虫了,我又要被吐槽了吧.......有很多自己懂的东西,但是面对老张的

拷问......就都回答不上来了。

    

    周六...老卢对我说:“我感觉你是不是要考个研啊”

    我当时心里真的是一阵激动啊.......你干嘛当时要放老娘的鸽子,你那会儿....早点告诉我你想我考

我这会儿,我真的,自习室,挥汗如雨啊。现在都九月份了和我说,叫我怎么考....

    年纪越大,记性越差的啊........老卢说等我想考研究生的时候再去问他.....我真的会误会,他是真

的想我考研,想当我导师....我这个人.....总是容易一头热,总是容易,一厢情愿。即使是他现在和

我说,我都很心动,很想飞到南开,和他说:老师,你又胖了。

 

    哎..................................................................................

    

    说起来王叔最近一直在面试,我总觉得他面试到人了,老张就要走了。

    有点舍不得,毕竟在我找工作屡屡受挫之际是他向我伸出了手啊.......................很想孝敬一下他...哈哈哈哈

    不过还是那句话:聚散有时,未来可期

    反正我最后也不会留在上海,过几年就走了,就在心里祝福他吧。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值