Python 在Django,一个一个、多个和一个外国钥匙字段之间有什么区别?
我对Django模型中的关系有点难以理解Python 在Django,一个一个、多个和一个外国钥匙字段之间有什么区别?,python,django,many-to-many,foreign-key-relationship,one-to-one,Python,Django,Many To Many,Foreign Key Relationship,One To One,我对Django模型中的关系有点难以理解 有人能解释一下一个一个、多个和外国钥匙之间的区别吗?这里有两个问题: 一对一、多对多和外键关系(一般)有什么区别 他们与Django的具体区别是什么 这两个问题都很容易通过简单的谷歌搜索得到答案,但由于我无法在上面找到这个问题的确切答案,所以我将继续回答 请注意,在Django中,应该只在关系的一侧定义关系 外侨 外键关系通常称为多对一关系。请注意,这种关系的反面是一对多(Django提供了访问工具)。顾名思义,许多对象可能与一个对象相关 Person
有人能解释一下一个一个、多个和外国钥匙之间的区别吗?这里有两个问题:
外侨 外键关系通常称为多对一关系。请注意,这种关系的反面是一对多(Django提供了访问工具)。顾名思义,许多对象可能与一个对象相关
Person >--| Birthplace
^ ^
| |
Many One
在本例中,一个人可能只有一个出生地,但一个出生地可能与许多人有关。让我们看看Django中的这个例子。假设这些是我们的模型:
class Birthplace(models.Model):
city = models.CharField(max_length=75)
state = models.CharField(max_length=25)
def __unicode__(self):
return "".join(self.city, ", ", self.state)
class Person(models.Model):
name = models.CharField(max_length=50)
birthplace = models.ForeignKey(Birthplace)
def __unicode__(self):
return self.name
您可以看到,出生地
模型中没有定义任何关系,而外键
关系是在个人
模型中定义的。假设我们创建了以下模型实例(显然不是Python语法):
- 出生地:德克萨斯州达拉斯
- 出生地:纽约市,纽约
- 人:约翰·史密斯,出生地:(德克萨斯州达拉斯)
- 人:玛丽亚·李,出生地:(德克萨斯州达拉斯)
- 人物:丹尼尔·李,出生地:(纽约市,纽约)
/manage.py shell
是您的朋友!)
请注意,我们可以通过在模型关系中设置related_name
关键字参数来更改此管理器的名称。因此,我们将Person
模型中的出生地
字段更改为:
birthplace = models.ForeignKey(Birthplace, related_name="people")
现在,我们可以用一个漂亮的名字来访问这种反向关系:
>> place.people.all()
[<Person: John Smith>, <Person: Maria Lee>]
让我们看看这个在Django。我不会费心定义用户模型,因为Django为我们定义了它。但是请注意,Django建议使用Django.contrib.auth.get\u user\u model()
导入用户,因此我们将这样做。剖面模型可定义如下:
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL) # Note that Django suggests getting the User from the settings for relationship definitions
fruit = models.CharField(max_length=50, help_text="Favorite Fruit")
facebook = models.CharField(max_length=100, help_text="Facebook Username")
def __unicode__(self):
return "".join(self.fruit, " ", self.facebook)
>> Project.objects.all()
[<Project: Project 0>, <Project: Project 1>, <Project: Project 2>]
>> for proj in Project.objects.all():
.. print(proj)
.. proj.orders.all() # Note that we must access the `orders`
.. # field through its manager
.. print("")
Project 0
[]
Project 1
[<Order: Spaceship for NASA>]
Project 2
[<Order: Spaceship for NASA>, <Order: Race car for NASCAR>]
我们只需要一个拥有配置文件的用户就可以在shell中进行测试:
- 用户:johndt6
- 简介:用户:johndt6,“猕猴桃”,“诸如此类”
>> user = User.objects.all()[0]
>> user.username
johndt6
>> user.profile
<Profile: Kiwi blah_blah>
>> user.profile.fruit
Kiwi
>> profile = Profile.objects.get(user=user)
>> profile.user
<User: johndt6>
让我们将我们的模型定义为:
class Order(models.Model):
product = models.CharField(max_length=150) # Note that in reality, this would probably be better served by a Product model
customer = models.CharField(max_length=150) # The same may be said for customers
def __unicode__(self):
return "".join(self.product, " for ", self.customer)
class Project(models.Model):
orders = models.ManyToManyField(Order)
def __unicode__(self):
return "".join("Project ", str(self.id))
请注意,Django将为orders
字段创建一个RelatedManager
,以访问多对多关系
让我们创建模型的以下实例(使用我不一致的语法!):
- 命令:“宇宙飞船”,“美国宇航局”
- 命令:“潜艇”,“美国海军”
- 命令:“赛车”,“纳斯卡”
- 项目:订单:[]
- 项目:订单:[(订单:“宇宙飞船”、“NASA”)]
- 项目:订单:[(订单:“宇宙飞船”、“NASA”),(订单:“赛车”、“NASCAR”)]
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL) # Note that Django suggests getting the User from the settings for relationship definitions
fruit = models.CharField(max_length=50, help_text="Favorite Fruit")
facebook = models.CharField(max_length=100, help_text="Facebook Username")
def __unicode__(self):
return "".join(self.fruit, " ", self.facebook)
>> Project.objects.all()
[<Project: Project 0>, <Project: Project 1>, <Project: Project 2>]
>> for proj in Project.objects.all():
.. print(proj)
.. proj.orders.all() # Note that we must access the `orders`
.. # field through its manager
.. print("")
Project 0
[]
Project 1
[<Order: Spaceship for NASA>]
Project 2
[<Order: Spaceship for NASA>, <Order: Race car for NASCAR>]
因此,可以分别读取关系的每个“边”或方向。把它们挤在一起很方便
扩展其中一种关系可能更有意义:
+---- John Smith
|
Dallas|-------+---- Jane Doe
|
+---- Joe Smoe
资源
由@MarcB提供
Django文件:
这是一个DB概念,并不特定于Django:外键是如何指定这些关系的。我要补充的是,使用
ManyToManyField
在数据库中创建一个额外的表,该表将包含3个字段:pk和对连接表的2个引用(表1\u id,表2\u id)ManyToManyField
是标记的最佳选择(例如,如果您想用标记标记特定项目/产品/位置)。以下是ManyToManyField中间表中的文档-。
class Order(models.Model):
product = models.CharField(max_length=150) # Note that in reality, this would probably be better served by a Product model
customer = models.CharField(max_length=150) # The same may be said for customers
def __unicode__(self):
return "".join(self.product, " for ", self.customer)
class Project(models.Model):
orders = models.ManyToManyField(Order)
def __unicode__(self):
return "".join("Project ", str(self.id))
>> Project.objects.all()
[<Project: Project 0>, <Project: Project 1>, <Project: Project 2>]
>> for proj in Project.objects.all():
.. print(proj)
.. proj.orders.all() # Note that we must access the `orders`
.. # field through its manager
.. print("")
Project 0
[]
Project 1
[<Order: Spaceship for NASA>]
Project 2
[<Order: Spaceship for NASA>, <Order: Race car for NASCAR>]
>> order = Order.objects.filter(customer="NASA")[0]
>> order.project_set.all()
[<Project: Project 0>, <Project: Project 2>]
A --< B
A >-- B
+---- John Smith
|
Dallas|-------+---- Jane Doe
|
+---- Joe Smoe