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

时间:2021-01-02 17:10:57

I posted a similar question a while earlier, but this one is different. I have a model structure of related classes like:

我之前也提过一个类似的问题,但这次不同。我有一个相关类的模型结构,比如:

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)

I want to change the default value of ques_type in the derived class. How should i accomplish this?

我想更改派生类中的ques_type的默认值。我该怎么做呢?

3 个解决方案

#1


9  

First, in this use of inheritance it is (at least according to my tests) not possible to change the default of the field in the child class. MathQuestion and Question share the same field here, changing the default in the child class affects the field in the parent class.

首先,在使用继承时(至少根据我的测试)不可能更改子类中字段的默认值。MathQuestion和Question在这里共享同一个字段,更改子类中的默认值将影响父类中的字段。

Now if what only differs between MathQuestion and Question is the behaviour (so, MathQuestion doesn't add any fields besides those defined in Question), then you could make it a proxy model. That way, no database table is created for MathQuestion.

现在,如果MathQuestion和Question之间唯一的区别是行为(因此,除了定义在问题中的字段之外,MathQuestion不添加任何字段),那么您可以将其作为代理模型。这样,就不会为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


2  

Use a Form or ModelForm, on which you can override the field. For models, set the default value in it's __init__ method like so:

使用可以覆盖字段的表单或模型表单。对于模型,在它的__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

Note that this has to be done after calling the parent class init.

注意,这必须在调用父类init之后完成。

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

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

#3


0  

This is easy to do using a closure.

使用闭包很容易做到这一点。

from django.db import models

django。数据库导入模型

# 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

The closure allows you to define it how you like it.

闭包允许您以自己喜欢的方式定义它。

from django.db import models

django。数据库导入模型

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


9  

First, in this use of inheritance it is (at least according to my tests) not possible to change the default of the field in the child class. MathQuestion and Question share the same field here, changing the default in the child class affects the field in the parent class.

首先,在使用继承时(至少根据我的测试)不可能更改子类中字段的默认值。MathQuestion和Question在这里共享同一个字段,更改子类中的默认值将影响父类中的字段。

Now if what only differs between MathQuestion and Question is the behaviour (so, MathQuestion doesn't add any fields besides those defined in Question), then you could make it a proxy model. That way, no database table is created for MathQuestion.

现在,如果MathQuestion和Question之间唯一的区别是行为(因此,除了定义在问题中的字段之外,MathQuestion不添加任何字段),那么您可以将其作为代理模型。这样,就不会为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


2  

Use a Form or ModelForm, on which you can override the field. For models, set the default value in it's __init__ method like so:

使用可以覆盖字段的表单或模型表单。对于模型,在它的__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

Note that this has to be done after calling the parent class init.

注意,这必须在调用父类init之后完成。

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

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

#3


0  

This is easy to do using a closure.

使用闭包很容易做到这一点。

from django.db import models

django。数据库导入模型

# 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

The closure allows you to define it how you like it.

闭包允许您以自己喜欢的方式定义它。

from django.db import models

django。数据库导入模型

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.