django: изменить значение по умолчанию для расширенного модельного класса - PullRequest
13 голосов
/ 05 февраля 2011

Я уже публиковал похожий вопрос, но этот другой.У меня есть структура модели связанных классов, таких как:

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)

Я хочу изменить значение по умолчанию Ques_type в производном классе.Как мне это сделать?

Ответы [ 4 ]

11 голосов
/ 05 февраля 2011

Во-первых, при таком использовании наследования (по крайней мере, согласно моим тестам) невозможно изменить значение по умолчанию для поля в дочернем классе. MathQuestion и Question имеют здесь одно и то же поле, изменение значения по умолчанию в дочернем классе влияет на поле в родительском классе.

Теперь, если между MathQuestion и Question отличается только поведение (то есть, MathQuestion не добавляет никаких полей, кроме тех, которые определены в Question), вы можете сделать его прокси модель . Таким образом, таблица базы данных не создается для 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

Тест:

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 голосов
/ 19 марта 2013

Используйте Form или ModelForm, для которого вы можете переопределить поле.Для моделей установите значение по умолчанию в методе __init__ следующим образом:

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

Обратите внимание, что это должно быть сделано после вызова родительского класса init.

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

1 голос
/ 28 мая 2019

Примеры выше для моделей прокси. Если вам нужно изменить значение по умолчанию для модели, унаследованной от неабстрактной базовой модели, вы можете сделать следующее:

from django.db import models


class Base(models.Model):
    field_name = models.CharField(...)


class Child(Base):
    def __init__(self, *args, **kwargs):
        kwargs['field_name'] = kwargs.get('field_name') or 'default value'
        super().__init__(*args, **kwargs)

Который установит значение по умолчанию, если оно не было передано непосредственно на Model(...) или Model.objects.create(...).

1 голос
/ 28 марта 2011

Это легко сделать с помощью затвора.

из импортных моделей django.db

# 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

Закрытие позволяет вам определить, как вам нравится.

из импортных моделей django.db

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.
...