Here's what I'm trying to do. I'm wondering if someone can suggest a good approach:
这就是我想要做的。我想知道是否有人可以建议一个好方法:
models.py:
class Color(models.Model):
name = models.CharField(...
class Speed(models.Model):
name = models.CharField(...
class Dog(models.Model):
name = models.CharField(...
color = models.ForeignKey(Color...
speed = models.ForeignKey(Speed...
class DogRequest(models.Model):
dog = models.ForeignKey(Dog...
request_time = models.DateTimeField()
Now I want to have a page where a user can enter or edit a DogRequest, but the form should look like this:
现在我想要一个用户可以输入或编辑DogRequest的页面,但表单应如下所示:
Enter Dog Request:
---------------------
color (dropdown V)
speed (dropdown V)
|save|
So how would I design that form in the view? The problem is the user will be entering properties of a dog, but not a dog. So I need to find or create a dog record depending on what the user enters.
那么我如何在视图中设计该表单?问题是用户将输入狗的属性,而不是狗。因此,我需要根据用户输入的内容查找或创建狗记录。
So far I've tried something like this:
到目前为止,我尝试过这样的事情:
class DogRequestForm(ModelForm):
class Meta:
model = DogRequest
fields = ('request_time','color','speed')
color = forms.ModelChoiceField(queryset=Color.objects.all())
speed = forms.ModelChoiceField(queryset=Speed.objects.all())
Now assuming that even works, where do I put the code to figure out the Dog record to use (or create) depending on what's entered for color and speed? And how do I fill the form from a DogRequest?
现在假设即使有效,我在哪里可以根据输入的颜色和速度来确定使用(或创建)Dog记录的代码?我如何从DogRequest填写表格?
1 个解决方案
#1
8
I don't think you want to use a ModelForm here. It will never be valid without some hackery, since you won't have found or created the dog object before calling is_valid()
.
我不认为你想在这里使用ModelForm。没有一些hackery它永远不会有效,因为在调用is_valid()之前你不会找到或创建dog对象。
Instead, I'd just use a regular form, and then override the save method of DogRequest to find or create the dog.
相反,我只是使用常规表单,然后覆盖DogRequest的save方法来查找或创建狗。
Update: Responding to the followup question in the comment, I haven't tested this, but something like it should work.
更新:回应评论中的后续问题,我没有对此进行测试,但类似的东西应该有效。
class DogRequestForm(forms.Form):
id = forms.IntegerField(required=False, widget=forms.HiddenInput())
color = forms.ModelChoiceField(queryset=Color.objects.all())
speed = forms.ModelChoiceField(queryset=Speed.objects.all())
and then when you create an instance of this form for your edit view you need to instantiate it with something like this:
然后,当您为编辑视图创建此表单的实例时,需要使用以下内容对其进行实例化:
data = {
'id': dog_request_id,
'color': dog_color,
'speed': dog_speed,
}
form = DogRequestForm(data)
where you populate the current dog_request_id
, dog_color
and dog_speed
from your existing DogRequest
object.
从现有DogRequest对象填充当前dog_request_id,dog_color和dog_speed的位置。
#1
8
I don't think you want to use a ModelForm here. It will never be valid without some hackery, since you won't have found or created the dog object before calling is_valid()
.
我不认为你想在这里使用ModelForm。没有一些hackery它永远不会有效,因为在调用is_valid()之前你不会找到或创建dog对象。
Instead, I'd just use a regular form, and then override the save method of DogRequest to find or create the dog.
相反,我只是使用常规表单,然后覆盖DogRequest的save方法来查找或创建狗。
Update: Responding to the followup question in the comment, I haven't tested this, but something like it should work.
更新:回应评论中的后续问题,我没有对此进行测试,但类似的东西应该有效。
class DogRequestForm(forms.Form):
id = forms.IntegerField(required=False, widget=forms.HiddenInput())
color = forms.ModelChoiceField(queryset=Color.objects.all())
speed = forms.ModelChoiceField(queryset=Speed.objects.all())
and then when you create an instance of this form for your edit view you need to instantiate it with something like this:
然后,当您为编辑视图创建此表单的实例时,需要使用以下内容对其进行实例化:
data = {
'id': dog_request_id,
'color': dog_color,
'speed': dog_speed,
}
form = DogRequestForm(data)
where you populate the current dog_request_id
, dog_color
and dog_speed
from your existing DogRequest
object.
从现有DogRequest对象填充当前dog_request_id,dog_color和dog_speed的位置。