2011-02-05 19 views
12

Postawiłem podobne pytanie chwilę wcześniej, ale ten jest inny. Mam strukturę modelu powiązanych klas takich jak:django: Zmień domyślną wartość dla rozszerzonej klasy modelu

class Question(models.Model): 
    ques_type = models.SmallIntegerField(default=TYPE1, Choices= CHOICE_TYPES) 

class MathQuestion(Question): 
    //Need to change default value of ques_type here 
    // Ex: ques_type = models.SmallIntegerField(default=TYPE2, Choices= CHOICE_TYPES) 

Chcę zmienić domyślną wartość ques_type w klasie pochodnej. Jak powinienem to zrobić?

Odpowiedz

8

Po pierwsze, w tym sposobie dziedziczenia (przynajmniej w moich testach) nie można zmienić domyślnej wartości pola w klasie dziecka. MathQuestion i Question udostępniają to samo pole, zmiana wartości domyślnej w klasie podrzędnej wpływa na pole w klasie nadrzędnej.

Teraz, jeśli to, co różni się tylko między MathQuestion i Question jest zachowanie (tak, MathQuestion nie dodawać żadnych pól oprócz tych określonych w Question), a następnie można zrobić to proxy model. W ten sposób nie zostanie utworzona żadna tabela bazy danych dla MathQuestion.

from django.db import models 

class Question(models.Model): 
    ques_type = models.SmallIntegerField(default=2) 

class MathQuestion(Question): 

    def __init__(self, *args, **kwargs): 
     self._meta.get_field('ques_type').default = 3 
     super(MathQuestion, self).__init__(*args, **kwargs) 

    class Meta: 
     proxy = True 

Test:

In [1]: from bar.models import * 

In [2]: a=Question.objects.create() 

In [3]: a.ques_type 
Out[3]: 2 

In [4]: b=MathQuestion.objects.create() 

In [5]: b.ques_type 
Out[5]: 3 
+2

Dodaję nowe pola w klasie pochodnej. Metoda klasy pośredniej nie będzie działać. – Neo

+0

Nie można ustawić pola ques_type w metodzie __init__? – Neo

+0

@Neo Próbowałem, ale zgodnie z [dokumentacją] (http://docs.djangoproject.com/en/1.2/topics/db/models/#field-name-hiding-is-not-permitted) to nie jest possible: ** Jeśli klasa bazowa ma pole o nazwie author, nie można utworzyć innego pola modelu o nazwie author w żadnej klasie dziedziczącej z tej klasy bazowej. ** –

0

Łatwo to zrobić za pomocą zamknięcia.

z django.db modeli importowych

# You start here, but the default of 2 is not what you really want. 

class Question(models.Model): 
    ques_type = models.SmallIntegerField(default=2) 

class MathQuestion(Question): 

    def __init__(self, *args, **kwargs): 
     self._meta.get_field('ques_type').default = 3 
     super(MathQuestion, self).__init__(*args, **kwargs) 

    class Meta: 
     proxy = True 

Zamknięcie pozwala zdefiniować, jak wam się podoba.

z django.db modeli importowych

def mkQuestion(cl_default=2): 
    class i_Question(models.Model): 
     ques_type = models.SmallIntegerField(default=cl_default) 

    class i_MathQuestion(i_Question): 

     def __init__(self, *args, **kwargs): 
      super(MathQuestion, self).__init__(*args, **kwargs) 
    return i_MATHQUESTION 


MathQuestion = mkQuestion() 
MathQuestionDef3 = mkQuestion(3) 

# Now feel free to instantiate away. 
1

Użyj Form lub ModelForm, na którym można zmienić pole. Dla modeli, należy ustawić wartość domyślną w to __init__ metoda tak:

class Question(models.Model): 
    ques_type = models.SmallIntegerField(default=2) 

class MathQuestion(Question): 

    def __init__(self, *args, **kwargs): 
     super(MathQuestion, self).__init__(*args, **kwargs) 
     self.ques_type = 3 

    class Meta: 
     proxy = True 

Zauważ, że to musi być zrobione po wywołanie init klasy nadrzędnej.

https://docs.djangoproject.com/en/dev/topics/forms/modelforms/

Powiązane problemy