Programing

장고에서 일대 다 관계를 표현하는 방법

lottogame 2020. 6. 15. 08:16
반응형

장고에서 일대 다 관계를 표현하는 방법


지금 Django 모델을 정의 OneToManyField하고 있으며 모델 필드 유형 이 없다는 것을 깨달았습니다 . 나는 이것을 할 수있는 방법이 있다고 확신하므로 내가 무엇을 놓치고 있는지 잘 모르겠습니다. 나는 본질적으로 다음과 같은 것을 가지고있다 :

class Dude(models.Model):
    numbers = models.OneToManyField('PhoneNumber')

class PhoneNumber(models.Model):
    number = models.CharField()

이 경우 각각에 Dude여러 PhoneNumber개의을 가질 수 있지만 for 와 같은 인스턴스 를 소유하는 많은 다른 객체가있을 수 있으므로 관계 PhoneNumberDude소유 한 대상 을 알 필요가 없기 때문에 관계는 단방향이어야합니다. 예:PhoneNumberBusiness

class Business(models.Model):
    numbers = models.OneToManyField('PhoneNumber')

OneToManyField이런 종류의 관계를 나타 내기 위해 모델에서 무엇을 대체합니까 (존재하지 않음)? 일대 다 관계를 선언하는 것이 가장 쉬운 Hibernate / JPA에서 왔습니다.

@OneToMany
private List<PhoneNumber> phoneNumbers;

장고에서 이것을 어떻게 표현할 수 있습니까?


Django에서 일대 다 관계를 처리하려면을 사용해야 ForeignKey합니다.

ForeignKey에 대한 문서는 매우 포괄적이며 다음과 같은 모든 질문에 답변해야합니다.

https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey

귀하의 예에서 현재 구조를 통해 각 Dude는 하나의 번호를 가질 수 있으며 각 번호는 여러 Dudes (Business와 동일)에 속할 수 있습니다.

반대 관계를 원하면 PhoneNumber 모델에 두 개의 ForeignKey 필드 (하나는 Dude와 하나는 Business)를 추가해야합니다. 이를 통해 각 번호는 하나의 Dude 또는 하나의 비즈니스에 속할 수 있으며 Dudes 및 비즈니스는 여러 개의 번호를 소유 할 수 있습니다. 나는 이것이 당신이 무엇인지 생각합니다.

class Business(models.Model):
    ...
class Dude(models.Model):
    ...
class PhoneNumber(models.Model):
    dude = models.ForeignKey(Dude)
    business = models.ForeignKey(Business)

장고에서는 일대 다 관계를 ForeignKey라고합니다. 그것은 단지 그렇게보다는 가진, 그러나 한 방향으로 작동 number클래스의 속성을 Dude당신이 필요로하는 것

class Dude(models.Model):
    ...

class PhoneNumber(models.Model):
    dude = models.ForeignKey(Dude)

많은 모델 ForeignKey이 일대일 모델을 가질 수 있으므로 다음 PhoneNumber과 같은 두 번째 속성을 갖는 것이 유효 합니다.

class Business(models.Model):
    ...
class Dude(models.Model):
    ...
class PhoneNumber(models.Model):
    dude = models.ForeignKey(Dude)
    business = models.ForeignKey(Business)

당신은에 액세스 할 수 있습니다 PhoneNumberA의의를 Dude객체 dd.phonenumber_set.objects.all(), 다음을 위해 유사 할 Business객체입니다.


많은 OneToMany관계 측면 (예 : ManyToOne관계) 에서 외래 키를 사용하거나 ManyToMany고유 제약 조건으로 (어느쪽에 서든) 외래 키를 사용할 수 있습니다 .


더 명확하게 말하면, 장고에는 OneToMany가 없으며 ManyToOne 만 있습니다. 이것은 위에서 설명한 Foreignkey입니다. Foreignkey를 사용하여 OneToMany 관계를 설명 할 수 있지만 매우 표현력이 뛰어납니다.

그것에 관한 좋은 기사 : https://amir.rachum.com/blog/2013/06/15/a-case-for-a-onetomany-relationship-in-django/


django충분히 똑똑하다. 실제로 우리는 oneToMany필드 를 정의 할 필요가 없습니다 . 자동으로 생성됩니다 django:-). foreignKey관련 테이블 에만 정의하면 됩니다. 다시 말해, ManyToOne를 사용하여 관계 를 정의하기 만하면됩니다 foreignKey.

class Car(models.Model):
    // wheels = models.oneToMany() to get wheels of this car [**it is not required to define**].


class Wheel(models.Model):
    car = models.ForeignKey(Car, on_delete=models.CASCADE)  

특정 자동차의 바퀴 목록을 얻으려면 우리는 python's자동 생성 객체 를 사용할 것 wheel_set입니다. c위해 당신은 사용할 것입니다c.wheel_set.all()


"많은"모델이 모델 별 모델 생성을 정당화하지 않는 경우 (여기서는 아니지만 다른 사람들에게 도움이 될 수 있음), 다른 대안은 Django Contrib 패키지 를 통해 특정 PostgreSQL 데이터 유형에 의존하는 것입니다

Postgres can deal with Array or JSON data types, and this may be a nice workaround to handle One-To-Many when the many-ies can only be tied to a single entity of the one.

Postgres allows you to access single elements of the array, which means that queries can be really fast, and avoid application-level overheads. And of course, Django implements a cool API to leverage this feature.

It obviously has the disadvantage of not being portable to others database backend, but I thougt it still worth mentionning.

Hope it may help some people looking for ideas.


While rolling stone's answer is good, straightforward and functional, I think there are two things it does not solve.

  1. If OP wanted to enforce a phone number cannot belong to both a Dude and a Business
  2. The inescapable feeling of sadness as a result of defining the relationship on the PhoneNumber model and not on the Dude/Business models. When extra terrestrials come to Earth, and we want to add an Alien model, we need to modify the PhoneNumber (assuming the ETs have phone numbers) instead of simply adding a "phone_numbers" field to the Alien model.

Introduce the content types framework, which exposes some objects that allow us to create a "generic foreign key" on the PhoneNumber model. Then, we can define the reverse relationship on Dude and Business

from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models

class PhoneNumber(models.Model):
    number = models.CharField()

    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    owner = GenericForeignKey()

class Dude(models.Model):
    numbers = GenericRelation(PhoneNumber)

class Business(models.Model):
    numbers = GenericRelation(PhoneNumber)

See the docs for details, and perhaps check out this article for a quick tutorial.

Also, here is an article that argues against the use of Generic FKs.

참고URL : https://stackoverflow.com/questions/6928692/how-to-express-a-one-to-many-relationship-in-django

반응형