简体   繁体   English

Django模型ManyToMany和外键

[英]Django Models ManyToMany and Foreign Key

Trying to get a better handle on how django database relationships are handled. 试图更好地处理如何处理django数据库关系。 Any thoughts are appreciated. 任何想法都表示赞赏。

Considering the following example models: 考虑以下示例模型:

class Things(models.Model):
    name = models.CharField(max_length=20)

class Stuff(models.Model):
    name = models.CharField(max_length=20)
    information = models.ManyToManyField('Information')
    things = models.ForeignKey('Things')

class Information(models.Model):
    name = models.CharField(max_length=20)
    stuff = models.ForeignKey('Stuff')

An error results from syncdb : AttributeError: 'ManyToManyField' object has no attribute 'ForeignKey' . syncdb导致错误: AttributeError: 'ManyToManyField' object has no attribute 'ForeignKey' The error results if I include both the ManyToManyField and the Foreign Key fields in the Stuff model. 错误的结果,如果我同时包括ManyToManyFieldForeign Key在田里Stuff模型。

Is there a way that I can make both of these relationships exist? 有没有办法可以让这两种关系存在? Thanks for any ideas. 谢谢你的任何想法。

If you want to know how many information are linked to each stuff , django will provide a default manager that will allow you to go backwards; 如果你想知道有多少information链接到每个stuff ,django将提供一个默认的管理器 ,让你倒退; for this you don't need a foreign key in stuff . 为此,你不需要一个外键stuff

class Things(models.Model):
    name = models.CharField(max_length=20)

class Stuff(models.Model):
    name = models.CharField(max_length=20)
    information = models.ManyToManyField('Information')
    things = models.ForeignKey('Things')

class Information(models.Model):
    name = models.CharField(max_length=20)

This model will allow you to do queries like: 此模型将允许您执行以下查询:

  • "What is the information for stuff X ?" Xstuff什么information ?”
  • "For stuff Y , what information is linked?" “对于stuff Y ,链接了什么information ?”
  • "Find me all stuff and information for thing Z " “查找我的所有stuffinformationthing Z

In addition it will allow you have multiple information for each stuff and multiple stuff for each thing . 此外,它可以让你有多个information的每个stuff ,多stuff对每个thing

Writing down these questions at the start will help you develop accurate models without unnecessary links/relations in your database. 在开始时写下这些问题将有助于您开发准确的模型,而无需在数据库中建立不必要的链接/关系。

My version of django gives a bit more information: 我的django版本提供了更多信息:

Error: One or more models did not validate:
foo.stuff: Reverse query name for m2m field 'information' clashes with field 'Information.stuff'. Add a related_name argument to the definition for 'information'.
foo.information: Reverse query name for field 'stuff' clashes with m2m field 'Stuff.information'. Add a related_name argument to the definition for 'stuff'.

Which is probably enough to get you going. 这可能足以让你前进。 Define a related_name for both the ManyToManyField relationship and the ForeignKey relationship from Information to Stuff... 定义related_name同时为ManyToManyField关系和ForeignKey从信息到东西的关系...

information = models.ManyToManyField('Information', related_name='stuff_many_set')
stuff = models.ForeignKey('Stuff', related_name = 'info_set')

then syncdb will be happy. 然后syncdb会很高兴。 Of course, you should be sure that you need both the relationships. 当然,你应该确定你需要两种关系。 With the generic entity names here it looks like there may be some confusion. 使用通用实体名称,看起来可能存在一些混淆。

Fundamentally you would get an error like this: 从根本上说,你会得到这样的错误:

$python manage.py syncdb
Error: One or more models did not validate:
t.stuff: Reverse query name for m2m field 'information' clashes with field  'Information.stuff'. Add a related_name argument to the definition for 'information'.
t.information: Reverse query name for field 'stuff' clashes with m2m field 'Stuff.information'. Add a related_name argument to the definition for 'stuff'.

why? 为什么? simple you have two tables referencing each other, the problem here is that when reverse look ups are applied django will generate the same name, creating a clash. 很简单,你有两个相互引用的表,这里的问题是,当应用反向查找时,django将生成相同的名称,创建一个冲突。

To fix this issue, like the error states, you need to add related_name this way django knows how to distinguish the different reverse calls. 要解决此问题,如错误状态,您需要以这种方式添加related_name django知道如何区分不同的反向调用。

from django.db import models

class Things(models.Model):
    name = models.CharField(max_length=20)

class Stuff(models.Model):
    name = models.CharField(max_length=20)
    information = models.ManyToManyField('Information', related_name = 'information_information')
    things = models.ForeignKey('Things')

class Information(models.Model):
    name = models.CharField(max_length=20)
    stuff = models.ForeignKey('Stuff', related_name = 'information_stuff')

Sorry Im not very creative with the names, this should work. 对不起,我的名字不是很有创意,这应该有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM