나는 이것을 찾고 있어요 :
class Place(models.Model):
name = models.CharField(max_length=20)
rating = models.DecimalField()
class LongNamedRestaurant(Place): # Subclassing `Place`.
name = models.CharField(max_length=255) # Notice, I'm overriding `Place.name` to give it a longer length.
food_type = models.CharField(max_length=25)
이것은 내가 사용하고 싶은 버전입니다 (어떤 제안에도 열려 있지만) :
http://docs.djangoproject.com/en/dev/topics/db/models/#id7
장고에서 지원 되나요? 그렇지 않은 경우 유사한 결과를 얻을 수있는 방법이 있습니까?
답변
업데이트 된 답변 : 사람들이 댓글에서 언급했듯이 원래 답변은 질문에 제대로 답변하지 않았습니다. 실제로 LongNamedRestaurant
데이터베이스에서 생성 된 모델 만 Place
그렇지 않았습니다.
해결책은 “장소”를 나타내는 추상 모델을 만드는 것입니다. AbstractPlace
, 상속 :
class AbstractPlace(models.Model):
name = models.CharField(max_length=20)
rating = models.DecimalField()
class Meta:
abstract = True
class Place(AbstractPlace):
pass
class LongNamedRestaurant(AbstractPlace):
name = models.CharField(max_length=255)
food_type = models.CharField(max_length=25)
@Mark 답변 을 읽으십시오 . 그는 비추 상 클래스에서 상속 된 속성을 변경할 수없는 이유를 훌륭한 설명을 제공합니다.
(이것은 Django 1.10 이후에만 가능합니다. Django 1.10 이전에는 추상 클래스에서 상속 된 속성을 수정할 수 없었습니다.)
원래 답변
Django 1.10부터 가능합니다 ! 요청한대로해야합니다.
class Place(models.Model): name = models.CharField(max_length=20) rating = models.DecimalField() class Meta: abstract = True class LongNamedRestaurant(Place): # Subclassing `Place`. name = models.CharField(max_length=255) # Notice, I'm overriding `Place.name` to give it a longer length. food_type = models.CharField(max_length=25)
답변
아니요, 아닙니다 .
필드 이름 “숨기기”는 허용되지 않습니다.
일반적인 Python 클래스 상속에서는 자식 클래스가 부모 클래스의 모든 속성을 재정의하는 것이 허용됩니다. Django에서는
Field
인스턴스 인 속성에 대해 허용되지 않습니다 (적어도 현재는 아님). 기본 클래스에라는 필드가있는 경우 해당 기본 클래스 에서 상속되는 클래스에서author
호출author
되는 다른 모델 필드를 만들 수 없습니다 .
답변
그것은 추상이 아니면 불가능 LongNamedRestaurant
하며 Place
, 그 이유는 다음과 같습니다 . 클래스로서뿐만 아니라 데이터베이스에서도. place-table에는 모든 pure Place
및 모든 LongNamedRestaurant
. 장소 테이블에 대한 및 참조를 LongNamedRestaurant
사용하여 추가 테이블을 만듭니다 food_type
.
당신이한다면 Place.objects.all()
, 당신은 또한 인 모든 장소를 얻습니다 LongNamedRestaurant
. 그리고 그것은 Place
(없이 food_type
) 의 인스턴스가 될 것입니다 . 그래서 Place.name
와 LongNamedRestaurant.name
같은 데이터베이스 열을 공유하기 때문에 같은 유형이어야합니다.
나는 이것이 일반 모델에게 의미가 있다고 생각한다. 모든 식당은 하나의 장소이고, 적어도 그 장소에있는 모든 것이 있어야한다. 이러한 일관성은 데이터베이스 문제를 일으키지는 않지만 1.10 이전의 추상 모델에서는 가능하지 않은 이유 일 수도 있습니다. @lampslave가 언급했듯이 1.10에서 가능했습니다. 개인적으로주의를 기울이는 것이 좋습니다. Sub.x가 Super.x를 재정의하는 경우 Sub.x가 Super.x의 하위 클래스인지 확인하고 그렇지 않으면 Sub를 Super 대신 사용할 수 없습니다.
해결 방법 : AUTH_USER_MODEL
이메일 필드 만 변경해야하는 경우 상당한 코드 복제를 포함 하는 사용자 지정 사용자 모델 ( )을 만들 수 있습니다 . 또는 이메일을 그대로두고 모든 양식에 필요한지 확인할 수 있습니다. 다른 응용 프로그램에서 사용하는 경우 데이터베이스 무결성을 보장하지 않으며 다른 방식으로 작동하지 않습니다 (사용자 이름이 필요하지 않게하려면).
답변
참조 https://stackoverflow.com/a/6379556/15690를 :
class BaseMessage(models.Model):
is_public = models.BooleanField(default=False)
# some more fields...
class Meta:
abstract = True
class Message(BaseMessage):
# some fields...
Message._meta.get_field('is_public').default = True
답변
코드를 새 앱에 붙여넣고 INSTALLED_APPS에 앱을 추가하고 syncdb를 실행했습니다.
django.core.exceptions.FieldError: Local field 'name' in class 'LongNamedRestaurant' clashes with field of similar name from base class 'Place'
Django가 지원하지 않는 것 같습니다.
답변
이 멋진 코드 조각을 사용하면 추상 부모 클래스의 필드를 ‘재정의’할 수 있습니다.
def AbstractClassWithoutFieldsNamed(cls, *excl):
"""
Removes unwanted fields from abstract base classes.
Usage::
>>> from oscar.apps.address.abstract_models import AbstractBillingAddress
>>> from koe.meta import AbstractClassWithoutFieldsNamed as without
>>> class BillingAddress(without(AbstractBillingAddress, 'phone_number')):
... pass
"""
if cls._meta.abstract:
remove_fields = [f for f in cls._meta.local_fields if f.name in excl]
for f in remove_fields:
cls._meta.local_fields.remove(f)
return cls
else:
raise Exception("Not an abstract model")
추상 부모 클래스에서 필드가 제거되면 필요에 따라 자유롭게 재정의 할 수 있습니다.
이것은 내 작업이 아닙니다. 여기에서 원본 코드 : https://gist.github.com/specialunderwear/9d917ddacf3547b646ba
답변
Contribute_to_class를 다룰 수 있습니다.
class LongNamedRestaurant(Place):
food_type = models.CharField(max_length=25)
def __init__(self, *args, **kwargs):
super(LongNamedRestaurant, self).__init__(*args, **kwargs)
name = models.CharField(max_length=255)
name.contribute_to_class(self, 'name')
Syncdb가 잘 작동합니다. 이 예제를 시도하지 않았습니다. 제 경우에는 제약 조건 매개 변수를 재정의하므로 … 기다립니다!