我有两个与外键相关的模型:
# models.py
class TestSource(models.Model):
name = models.CharField(max_length=100)
class TestModel(models.Model):
name = models.CharField(max_length=100)
attribution = models.ForeignKey(TestSource, null=True)
默认情况下,django ModelForm会将其显示为带有 <option>
的 <select>
;但我更喜欢这个函数作为自由格式输入, <input type="text"/>
,并在幕后获取或创建必要的TestSource对象,然后将其与TestModel对象相关联 .
我试图定义一个自定义ModelForm和Field来完成这个:
# forms.py
class TestField(forms.TextInput):
def to_python(self, value):
return TestSource.objects.get_or_create(name=value)
class TestForm(ModelForm):
class Meta:
model=TestModel
widgets = {
'attribution' : TestField(attrs={'maxlength':'100'}),
}
不幸的是,我在尝试检查提交的表单上的 is_valid
时收到了 invalid literal for int() with base 10: 'test3'
. 我哪里错了?是他们更容易实现这一目标的方法吗?
4 回答
这样的事情应该有效:
这里有一些问题 .
首先,您已经定义了一个字段,而不是一个小部件,因此您无法在
widgets
字典中使用它 . 您需要覆盖表单顶层的字段声明 .其次
get_or_create
返回两个值:检索或创建的对象,以及显示是否创建的布尔值 . 您真的只想从to_python
方法返回第一个值 .我不确定其中任何一个是否会导致您的实际错误 . 您需要为我们发布实际回溯以确定 .
TestForm.attribution需要int值 - TestSource模型的关键 .
也许这个版本的模型对您来说会更方便:
取自:
How to make a modelform editable foreign key field in a django template?
此版本在 init 期间将s_address字段的初始数据设置为来自self的FK,这样,如果您将实例传递给表单,它将在您的字段中加载FK - 我添加了一个尝试,除了避免ObjectDoesNotExist错误,以便在有或没有数据传递给表单的情况下工作 .
虽然,我很想知道是否有更简单的内置Django覆盖 .