我前一段时间发布了一个类似的问题,但这个问题有所不同。我有一个相关类的模型结构,如:
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的默认值。我该怎么做到这一点?
答案 0 :(得分:11)
首先,在继承的使用中,(至少根据我的测试)不可能更改子类中字段的默认值。 MathQuestion
和Question
在此处共享相同的字段,更改子类中的默认值会影响父类中的字段。
现在,如果MathQuestion
和Question
之间只有不同的行为(那么,MathQuestion
除Question
中定义的字段外,不添加任何字段),那么你可以使它成为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)
使用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/
答案 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(...)
上直接传递默认值,则会设置默认值。