В чем разница между OneToOne, ManyToMany и полем ForeignKey в Джанго?
У меня возникли некоторые трудности с головой вокруг отношений в моделях Django.
может кто-нибудь объяснить, в чем разница между OneToOne, ManyToMany и ForeignKey?
1 ответов
Ну, здесь по существу два вопроса:
- в чем разница (в общем) Между один к одному, многие ко многим, и отношения внешнего ключа
- каковы их различия, характерные для Django.
на оба этих вопроса довольно легко ответить с помощью простого поиска Google, но, поскольку я не могу найти точный обман этого вопроса на SO, я пойду вперед и отвечу.
обратите внимание, что в Django, отношения должно быть определено только с одной стороны отношений.
иностранный ключ
отношение внешнего ключа обычно известно как отношение "многие к одному". Обратите внимание, что обратная сторона этого отношения-один ко многим (который Django предоставляет инструменты для доступа). Как следует из названия, многие объекты могут быть связаны с одной.
Person <--> Birthplace
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
вы можете видеть, что никакие отношения не определены в Birthplace
модель, и ForeignKey
отношение определяется в пределах Person
модель. Скажем, мы создаем следующие модели (очевидно, не в синтаксисе Python):
- Место Рождения: Даллас, Штат Техас
- Место Рождения: Нью-Йорк, Нью-Йорк
- Персона: Джон Смит, Место Рождения: (Даллас, Техас)
- Лицо: Мария Ли, Место Рождения: (Даллас, Техас)
- Человек: Дэниел Ли, Место Рождения: (Нью-Йорк, Нью-Йорк)
теперь мы можем видеть, как Django позволяет нам использовать эти отношения (обратите внимание, что ./manage.py shell
- ваш друг!):
>> from somewhere.models import Birthplace, Person
>> Person.objects.all()
[<Person: John Smith>, <Person: Maria Lee>, <Person: Daniel Lee>]
>> Birthplace.objects.all()
[<Birthplace: Dallas, Texas>, <Birthplace: New York City, New York>]
вы можете увидеть наши созданные модели. Теперь давайте проверим чье-то место рождения:
>> person = Person.object.get(name="John Smith")
>> person.birthplace
<Birthplace: Dallas, Texas>
>> person.birthplace.city
Dallas
предположим, вы хотите видеть всех людей с данным местом рождения. Как я уже говорил ранее, Django позволяет получить доступ к обратным отношениям. От по умолчанию Django создает менеджер (RelatedManager
) на вашей модели, чтобы справиться с этим, названный <model>_set
, где <model>
- название модели в нижнем регистре.
>> place = Birthplace.objects.get(city="Dallas")
>> place.person_set.all()
[<Person: John Smith>, <Person: Maria Lee>]
обратите внимание, что мы можем изменить имя этого менеджера, установив related_name
аргумент ключевого слова в нашем модельном отношении. Итак, мы изменим : приказ: []
мы можем получить доступ к этим отношениям следующим образом:
>> 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>]
обратите внимание, что заказ НАСА связано с 2 проектами, а заказ ВМС США не связан ни с одним. Также обратите внимание, что один проект не имеет заказов, а один имеет несколько.
мы также можем получить доступ к отношениям в обратном порядке так же, как и раньше:
>> order = Order.objects.filter(customer="NASA")[0]
>> order.project_set.all()
[<Project: Project 0>, <Project: Project 2>]
ресурсы
хорошее объяснение отношений БД предоставлено @MarcB