【发布时间】:2012-03-16 09:38:14
【问题描述】:
我有一个带有 get_form 方法的模型。
# models.py
from model_utils.managers import InheritanceManager
from breathingactivities.forms import ParentRecordForm, ChildRecordForm
class ParentRecord(models.Model):
....
objects = InheritanceManager()
def get_fields(self, exclude=('user')):
fields = self._meta.fields
return [(f.verbose_name, f.value_to_string(self)) for f in fields if not exclude.__contains__(f.name)]
@classmethod
def get_form(self, *args, **kwargs):
return ParentRecordForm
class ChildRecord(ParentRecord):
....
duration = DurationField(
_('Duration'),
help_text=_('placeholder'))
@classmethod
def get_form(self, *args, **kwargs):
return ChildRecordForm
我有一个视图,它使用这个 get_form 方法来确定给定对象的正确形式。
# views.py
class ParentRecordUpdateView(UpdateView):
model = ParentRecord
form_class = ParentRecordForm
template_name = 'parentrecords/create.html'
def get_object(self, **kwargs):
return ParentRecord.objects.get_subclass(slug=self.kwargs['slug'])
def get_form_class(self, *args, **kwargs):
form_class = self.model.objects.get_subclass(slug=self.kwargs['slug']).get_form()
return form_class
def get_form_kwargs(self):
kwargs = super(ParentRecordUpdateView, self).get_form_kwargs()
kwargs.update({'user': self.request.user})
return kwargs
我正在使用 django-model-utils 中的 InheritanceManager,因此当我查询父类时,我得到了一个干净的子类 API - 这就是 get_subclass() 的东西,这就是我的视图与 ParentRecord 一起使用的原因。
这一切都很好。我通过控制台看到确实 form_class 是我期望的表单类,例如当实例是 ChildRecord 时的 ChildRecordForm。
在我的 forms.py 中,我不能只导入 models.ParentRecord 和 models.ChildRecord,因为我在我的 models.py 中导入这些表单,因此会引发 Django 无法导入这些模型的错误。我猜是因为循环进口。
所以,我试试这个:
# forms.py
from django.db.models import get_model
class ParentRecordForm(forms.ModelForm):
def __init__(self, user, *args, **kwargs):
super (ParentRecordForm, self).__init__(*args, **kwargs)
class Meta:
model = get_model('model', 'ParentRecord')
exclude = ('user')
class ChildRecordForm(forms.ModelForm):
def __init__(self, user, *args, **kwargs):
super (ChildRecordForm, self).__init__(*args, **kwargs)
class Meta:
model = get_model('model', 'ParentRecord')
exclude = ('user')
但是,这些表单的模型总是返回 None。
我去传递 ChildRecordForm 一些完全不相关的模型,我可以从项目中的不同应用程序导入这些模型,例如:
# forms.py
from another_app import AnotherModel
class ChildRecordForm(forms.ModelForm):
def __init__(self, user, *args, **kwargs):
super (ChildRecordForm, self).__init__(*args, **kwargs)
class Meta:
model = AnotherModel
exclude = ('user')
然后它起作用了,意思是,表单返回AnotherModel的字段。
所以,当我使用 get_model() 为模型声明值时,我无法弄清楚为什么 get_model() 在 shell 中对我有用,但在表单类中却不行。
【问题讨论】:
-
就风格而言,
classmethod的第一个参数通常命名为cls,而不是self。 -
好吧,我不知道。
标签: django django-models django-forms django-views