在我当前的代码中(见下文),我从下拉选择字段中检索选定的值,例如值“ 1”。
recipe_choice = request.GET.get('recipe_select', False)
我在IF逻辑中使用此值来选择不同的形式,例如
if recipe_choice == '1':
ingredients_form = HamburgerForm(request.POST)
然后,我返回一个由下拉选择字段和所选表单组成的上下文。
当我将其作为函数调用时,一切正常,可以使用“请求”将下拉选项提取为GET。
例如作为功能:
path('cooking/', cooking, name="cooking")
但是,我想问一下,当改用基于类的FormView时如何获得相同的结果,例如:
path('cooking/', CookingView.as_view(), name="cooking")
我遇到的问题是,我无法从下拉列表中检索选定的值,也无法在get_context_data中找到要在IF语句中使用的值,因此无法将旧函数转换为新的CookingView(FormView):
class CookingView(FormView):
form_class = CookingForm
template_name = 'form/cooking.html'
def get_context_data(self, **kwargs):
"""
# some logic to get a desired form, such as
ingredients_form = []
if recipe_choice == '1':
ingredients_form = HamburgerForm(request.POST)
elif recipe_choice == '2':
ingredients_form = PancakeForm(request.POST)
"""
context = super(CookingView, self).get_context_data(**kwargs)
context['ingridients_form'] = ingredients_form
return context
问:如何将这种逻辑放入基于类的FormView中?
下面,我提供了当前有效的代码(作为函数)。
views.py
def cooking(request):
context = {}
recipe_choice = request.GET.get('recipe_select', False)
ingredients_form = []
if recipe_choice == '1':
ingredients_form = HamburgerForm(request.POST)
elif recipe_choice == '2':
ingredients_form = PancakeForm(request.POST)
context['cookbook_form'] = CookingForm(request.GET or None)
context['ingridients_form'] = ingredients_form
return render(request, 'form/cooking.html', context)
models.py
class Ingridients(models.Model):
# for hamburgers
cheese = models.IntegerField(default=0)
ham = models.IntegerField(default=0)
onion = models.IntegerField(default=0)
bread = models.IntegerField(default=0)
ketchup = models.IntegerField(default=0)
# for pancakes
milk = models.IntegerField(default=0)
butter = models.IntegerField(default=0)
honey = models.IntegerField(default=0)
eggs = models.IntegerField(default=0)
forms.py
class CookingForm(Form):
RECIPES = (
(1, 'Hamburger'),
(2, 'Pancakes')
)
recipe_select = ChoiceField(choices=RECIPES)
class HamburgerForm(forms.ModelForm):
class Meta:
model = Ingridients
fields = ['cheese', 'ham', 'onion', 'bread', 'ketchup']
class PancakeForm(forms.ModelForm):
class Meta:
model = Ingridients
fields = ['milk', 'butter', 'honey', 'eggs']
cooking.html
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id="cookselect_form" method="GET">
{{ cookbook_form|crispy }}
<div class="btn-group btn-group-justified" role="group">
<div class="btn-group" role="group">
<button class="btn btn-primary" type="submit">Choose Recipe</button>
</div>
</div>
</form>
<form id="ingridientslist_form" method="POST">
{% csrf_token %}
{% crispy ingridients_form %}
</form>
</body>
</html>
答案 0 :(得分:1)
我认为您可以这样处理:
我要重写get_form_class
方法,以确定在HamburgerForm和PancakeForm之间呈现哪种形式。然后,我将CookingForm
作为上下文传递给get_context_data
方法。
class CookingView(FormView):
template_name = 'form/cooking.html'
success_url = '/some_url/'
def get_form_class(self):
recipe_choice = self.request.GET.get('recipe_select', '1')
if recipe_choice == '1':
return HamburgerForm
elif recipe_choice == '2':
return PancakeForm
def get_context_data(self, **kwargs):
context = super(CookingView, self).get_context_data(**kwargs)
context['cookbook_form'] = CookingForm()
return context
我也正在更新模板(使用form
而不是ingridients_form
)。
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id="cookselect_form" method="GET">
{{ cookbook_form|crispy }}
<div class="btn-group btn-group-justified" role="group">
<div class="btn-group" role="group">
<button class="btn btn-primary" type="submit">Choose Recipe</button>
</div>
</div>
</form>
<form id="ingridientslist_form" method="POST">
{% csrf_token %}
{% crispy form %}
</form>
</body>
</html>