2012-06-30 2 views
2

원하는 공통된 위치 모델을 원한다면 위치를 필요로하는 다양한 고급 모델을 참조해야합니다.Django 관리자 인라인 및 스키마 디자인

게시자와 건물에 대한 더 높은 수준의 정보와 각각에 대한 위치 정보를 입력 할 수있는 여러 부분 형식 (인라인)으로 관리자에게 내 사용자를 표시하려고합니다. 인라인 시스템은 이런 식으로 작동하지 않는 것 같습니다.

분명히, 나에게 매우 표준적인 문제처럼 보이기 때문에 분명히 뭔가 잘못하고 있습니다. 내 스키마 디자인이 골칫거리니까?

나는 바보로 인라인 시스템을 사용합니까? 각각의 상위 레벨 객체에 대한 Location의 하위 클래스를 수행하고 싶지 않습니다. 상위 레벨 객체가 소유하고있는 다른 위치와는 다른 방식으로 위치를 조작하고 싶기 때문입니다 (메일 링리스트 또는 지형 검색).

models.py: 
... 
class Location(models.Model): 
    """ 
    A geographical address 
    """ 
# Standard Location stuff 
    address_line1 = models.CharField("Address line 1", max_length = 45, null=True, blank=True) 
    ... 

class Publisher(models.Model): 
    """ 
    Contains Publisher information for publishers of yearbooks. Replaces Institution from 1.x 
    """ 
    name = models.CharField(max_length=100, null=False, help_text="Name of publisher, e.g. University of Kansas") 
    groups = models.ManyToManyField(Group, help_text="Select groups that this publisher owns. Usually just one, but multiple groups are possible.") 
    is_active = models.BooleanField(help_text="Check this box to enable this publisher.") 
    location = models.OneToOneField(Location) 
    ... 

class Building(models.Model): 
    """ 
    Contains Building Information 
    """ 
    name = models.CharField(max_length=100, null=False, help_text="Name of building, e.g. Physical Sciences") 
    is_active = models.BooleanField(help_text="Check this box to enable this building.") 
    location = models.OneToOneField(Location) 
    ... 

admin.py: 
... 
class LocationInline(generic.GenericStackedInline): 
    model = Location 
    max_num = 1 
    extra = 1 

class PublisherAdmin(admin.ModelAdmin): 
    model = Publisher 
    inlines = [ LocationInline, 
    ] 

class BuildingAdmin(admin.ModelAdmin): 
    model = Building 
    inlines = [ LocationInline, 
    ] 

admin.site.register(Publisher, PublisherAdmin) 
admin.site.register(Building, BuildingAdmin) 
내가 인라인 개체를받을 수 있나요 및 편집 할 수 있습니다 경우에도이를 할 때, 관계 거꾸로 보인다

# Support reverse lookup for admin 
    object_id = models.PositiveIntegerField() 
    content_type = models.ForeignKey(ContentType) 
    of   = generic.GenericForeignKey('content_type', 'object_id') 

:

나는 위치 모델이 추가하여로드 인라인을 강제로 제시 할 수 있습니다 나에게, 그것을 만든 객체에 ID를 저장하는 Location.

모든 것이 훌륭하게 작동하도록 권장되는 스키마 변경 (장고가 너무 뛰어남) 또는 거꾸로 보이는 것들을 이해하기위한 트릭입니다.

답변

1

첫 번째로, OneToOneField가 아닌 ForeignKey를 원한다고 생각합니다. 그렇지 않으면 게시자 및 건물 모델에 위치 필드를 추가하는 것뿐입니다. 그런 다음 건물 및 게시자 관리에 필요할 경우 위치를 선택하기위한 드롭 다운과 필요한 경우 새 위치를 추가하기위한 링크가 표시됩니다.

건물/게시자 당 하나의 위치 인스턴스를 실제로 갖고 싶다면 인라인 모델은 제네릭을 추가하지 않으면 인라인 모델에 부모 모델을 가리키는 ForeignKey가 있어야하기 때문에 인라인으로 편집 할 수 없습니다 외래 키. 이것은 '뒤로'는 아닙니다. 유형에 관계없이 객체가 다른 객체에 부착 될 수 있도록하려는 경우 유효한 옵션입니다.

+0

그게 제가 그렉을 놓친 것입니다. 어떤 인식을 가진 '부모'객체없이 _itself_를 다른 객체에 붙이는 개념. 내 OneToOne 필드는 그 상황에서 불필요합니다. 알았다. 고맙습니다. –

1

도메인 모델과 관련하여 "올바른 방법"이 없기 때문에 특정 응용 프로그램 요구 사항에 따라 다릅니다.

WRT/문제 :

OneToOne 필드 (그렉 했나요로) 모델 인스턴스 당 하나 개의 위치에 모델을 제한 하지 개념적으로 단지 모델에서 직접 위치의 필드를 고집 매우 다르다. wrt/DRY/factorisation/reuse 등을 사용하면 모델 상속을 사용하여이 작업을 수행 할 수 있습니다. 추상 (또는 앱의 경우 의미가있는 경우 구체적으로 말하면) 위치 모델입니다.

ForeignKey 솔루션은 게시자 및 건물 모델을 여전히 하나의 위치로 제한하지만 원하는 위치는 다른 게시자 및/또는 건물 인스턴스간에 공유 될 수 있습니다. 즉, 지정된 위치를 편집하면 관련된 모든 인스턴스가 반영됩니다 (원하지 않는 부작용은 여기에주의하십시오).

위치 모델에서 GenericForeignKey를 사용하면 특정 위치 인스턴스가 에 속하고 관련 개체에만 속함을 의미합니다.위의 솔루션과 마찬가지로 부작용이 없지만 동일한 값을 가진 중복 위치 (예 : 건물의 경우 하나, 게시자의 경우)가있을 ​​수 있으며 특정 위치에 대한 모든 관련 개체를 조회 할 수 없습니다 (또는 적어도 그렇게 쉽게). 또한 게시자 또는 건물 인스턴스가 두 개 이상의 위치를 ​​차지하는 것을 막을 수는 없으며 다시 한 번 괜찮을 수도 있습니다. wrt/Location 인스턴스에 속한 객체의 "id를 저장하는"인스턴스는 실제로이 디자인 선택의 의미입니다. Location은 다른 객체, 기간에 속합니다.

Django의 admin 앱의 기본 동작을 중심으로 디자인하는 것이 가장 현명한 방법은 아닙니다. 먼저 응용 프로그램 (그리고 게시자 및 건물에 대한 필요성이 다를 수 있음)에 적합한 지 결정한 다음 필요에 맞게 관리자를 확장해야합니다.

+0

답변 해 주셔서 감사합니다. 저는 FK와 OneToOne의 일반적인 한계를 알고 있습니다. Greg는 아래의 대답에서 나를 분류했다. 내 입장에서는 개념적으로 어지럽 았고, 부모로부터 자식에게 앞으로의 참조를해야한다고 생각했습니다. 실제로, 실제로 원하는 것은 _itself_를 임의의 부모에게 첨부 할 수있는 자식입니다. –