django:更改扩展模型类的默认值

时间:2011-02-05 00:22:53

标签: python django django-models

我前一段时间发布了一个类似的问题,但这个问题有所不同。我有一个相关类的模型结构,如:

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 个答案:

答案 0 :(得分:11)

首先,在继承的使用中,(至少根据我的测试)不可能更改子类中字段的默认值。 MathQuestionQuestion在此处共享相同的字段,更改子类中的默认值会影响父类中的字段。

现在,如果MathQuestionQuestion之间只有不同的行为(那么,MathQuestionQuestion中定义的字段外,不添加任何字段),那么你可以使它成为proxy model。这样,就没有为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

答案 1 :(得分:2)

使用FormModelForm,您可以覆盖该字段。对于模型,请在其__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/

答案 2 :(得分:1)

使用闭包很容易做到。

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

答案 3 :(得分:0)

以上示例适用于代理模型。如果您需要更改从非抽象基础模型继承的模型的默认设置,可以执行以下操作:

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(...)上直接传递默认值,则会设置默认值。