지금 Django 모델을 정의 OneToManyField
하고 있으며 모델 필드 유형 이 없다는 것을 깨달았습니다 . 나는 이것을 할 수있는 방법이 있다고 확신하므로 내가 무엇을 놓치고 있는지 잘 모르겠습니다. 나는 본질적으로 다음과 같은 것을 가지고있다 :
class Dude(models.Model):
numbers = models.OneToManyField('PhoneNumber')
class PhoneNumber(models.Model):
number = models.CharField()
이 경우 각각에 Dude
여러 PhoneNumber
개의을 가질 수 있지만 for 와 같은 인스턴스 를 소유하는 많은 다른 객체가있을 수 있으므로 관계 PhoneNumber
를 Dude
소유 한 대상 을 알 필요가 없기 때문에 관계는 단방향이어야합니다. 예:PhoneNumber
Business
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)
당신은에 액세스 할 수 있습니다 PhoneNumber
A의의를 Dude
객체 d
로 d.phonenumber_set.objects.all()
, 다음을 위해 유사 할 Business
객체입니다.
답변
더 명확하게 말하면 장고에는 OneToMany가 없으며 ManyToOne 만 있습니다. 이것은 위에서 설명한 Foreignkey입니다. Foreignkey를 사용하여 OneToMany 관계를 설명 할 수 있지만 그 표현은 매우 표현력이 없습니다.
그것에 관한 좋은 기사 :
https://amir.rachum.com/blog/2013/06/15/a-case-for-a-onetomany-relationship-in-django/
답변
OneToMany
관계의 많은 측면 (예 : ManyToOne
관계) 에서 외래 키를 사용하거나 ManyToMany
고유 제약 조건으로 (어느쪽에 서든) 외래 키를 사용할 수 있습니다 .
답변
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()
답변
하지만 롤링 스톤 (Rolling Stone) ‘의 대답은 간단하고 기능 좋은이다, 나는 그것이 해결되지 않는 두 가지가 있다고 생각합니다.
- OP가 전화 번호를 시행하고자한다면 Dude와 Business 모두에 속할 수 없습니다
- Dude / Business 모델이 아니라 PhoneNumber 모델에 관계를 정의한 결과 피할 수없는 슬픔의 느낌. 추가 지상파가 지구에 와서 외계인 모델을 추가하려는 경우 단순히 외계인 모델에 “phone_numbers”필드를 추가하는 대신 ET에 전화 번호가 있다고 가정하여 PhoneNumber를 수정해야합니다.
콘텐츠 유형 프레임 워크를 도입하면 PhoneNumber 모델에서 “일반 외래 키”를 작성할 수있는 일부 오브젝트가 노출됩니다. 그런 다음 Dude와 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)
자세한 내용은 문서 를 참조 하고 빠른 자습서는 이 기사 를 참조하십시오 .
또한 다음은 Generic FK 사용에 반대 하는 기사 입니다 .
답변
“많은”모델이 모델 별 모델 생성을 정당화하지 않는 경우 (여기서는 아니지만 다른 사람들에게 도움이 될 수 있음), 다른 대안은 Django Contrib 패키지 를 통해 특정 PostgreSQL 데이터 유형에 의존하는 것입니다
Postgres는 Array 또는 JSON 데이터 형식을 처리 할 수 있으며, 여러 항목을 하나 의 단일 엔터티에만 연결할 수있는 경우 일대 다를 처리하는 좋은 해결 방법이 될 수 있습니다 .
Postgres를 사용하면 어레이의 단일 요소에 액세스 할 수 있으므로 쿼리가 실제로 빠르며 애플리케이션 수준의 오버 헤드를 피할 수 있습니다. 물론 Django는 이 기능을 활용 하기 위해 멋진 API 를 구현 합니다.
분명히 다른 데이터베이스 백엔드에 이식 할 수 없다는 단점이 있지만 여전히 언급 할 가치가 있습니다.
아이디어를 찾는 사람들에게 도움이되기를 바랍니다.
