实验所用的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,难受。
深夜吐槽系列:
明天又是周一,又要上班了。上周五的时候因为这个多对多和外键,被老张吐槽个半死。
周五下班和另一个同事一起走的,结果得知他把俩人的工作一起全部做完了,心里一阵抽搐。
觉得自己好菜,本来想看文档的,但是看别人写的东西总是不如自己直接做来的记忆深刻。所以
熬了会儿夜,毕竟这个周末我又没看书,至少把这个 外键 和 多对多 搞清楚怎么用,是什么关系
搞懂了也算是...没白过了。
而且周一我该开始弄爬虫了,我又要被吐槽了吧.......有很多自己懂的东西,但是面对老张的
拷问......就都回答不上来了。
周六...老卢对我说:“我感觉你是不是要考个研啊”
我当时心里真的是一阵激动啊.......你干嘛当时要放老娘的鸽子,你那会儿....早点告诉我你想我考
我这会儿,我真的,自习室,挥汗如雨啊。现在都九月份了和我说,叫我怎么考....
年纪越大,记性越差的啊........老卢说等我想考研究生的时候再去问他.....我真的会误会,他是真
的想我考研,想当我导师....我这个人.....总是容易一头热,总是容易,一厢情愿。即使是他现在和
我说,我都很心动,很想飞到南开,和他说:老师,你又胖了。
哎..................................................................................
说起来王叔最近一直在面试,我总觉得他面试到人了,老张就要走了。
有点舍不得,毕竟在我找工作屡屡受挫之际是他向我伸出了手啊.......................很想孝敬一下他...哈哈哈哈
不过还是那句话:聚散有时,未来可期
反正我最后也不会留在上海,过几年就走了,就在心里祝福他吧。