Django模型表单:显示OneToMany字段的查询表单和句柄请求 [英] Django Model Form: show query form and handle post request for OneToMany fields

查看:119
本文介绍了Django模型表单:显示OneToMany字段的查询表单和句柄请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Django的新手,在google / SO搜索后找不到类似的问题。



我有一个名为问题的模型,它有多个(2 -4)选择并定义如下:

  class Question(models.Model):
name = models.CharField (max_length = 128)
class Choice(models.Model):
name = models.CharField(max_length = 256)
is_correct = models.BooleanField(default = False)
问题= models.ForeignKey(Question,on_delete = models.CASCADE)

在多个选择中只有一个是正确的



我想做什么:在一个页面中,用户可以连同多个选项提交问题,这里是一个UI草稿:





我的第一个问题:我已经定义了ModelForm,但不知道如何添加选择字段到QuestionForm:

 类QuestionForm(ModelForm):
name = forms.CharField(max_length = 128 )
description = forms.CharField(max_length = 256)
class Meta:
model = Question
fields = ['name','description']

class ChoiceForm(ModelForm):
name = forms.CharField(max_length = 256)
is_correct = forms.BooleanField()
class Meta:
model = Choice
fields = ['name','is_correct']

可以使用ModelForm渲染我的第二个问题是:如果使用点击提交按钮,我使用AJAX将json数据发送到后台服务器,这里是一个例子的表单数据:

  name:question1 
choices [] [name]:choice1
choices [] [is_correct]:1
choices [] [name]:choice2
choices [] [is_correct]:0

这是我的代码handlin g请求:

  form = QuestionForm(request.POST)
如果form.is_valid():
问题= form.save()

如何从请求中解析选择?
如何从POST请求中解析多个选择部分的数据?



再次,我是Django的新手,任何回答/建议都非常感谢

解决方案

你的模型似乎是正确的,为了能够在你的模板中添加多个选择,你需要一个< href =https://docs.djangoproject.com/en/1.9/topics/forms/formsets/ =nofollow> formset 。此外,您可以将模板中的表单和表单放在同一个HTML表单中,并将其单独验证。每个人只关心与他们相关的POST数据。例如:



template.html

 < form method =postaction => 
{%csrf_token%}
{{choices_formset.management_form}}<! - django用于管理表单 - >
{{question_form.as_p}}
{choice for forms_formset%}中的表单
{{form.as_p}}
{%endfor%}
<按钮类型= '提交' >提交< /按钮>
< / form>

views.py

  from django.db import IntegrityError,transaction 
from django.shortcuts import redirect
from django.forms.formsets import formset_factory
from django.core.urlresolvers import reverse

def new_question(request):
ChoicesFormset = formset_factory(ChoicesForm)
如果request.method =='POST' :
question_form = QuestionForm(request.POST)
choices_formset = ChoicesFormset(request.POST)
如果question_form.is_valid():
question = Question(** question_form.cleaned_data)
如果choices_formset.is_valid():
question.save()
new_choice_list = list()
append_choice = new_choice_list.append
for choices_formset中的
form.cleaned_data.update({'question':question})
append_choice(Choice(** form.cleaned_data))
try:
with transaction.atomic():
Choice.objects.bulk_create(new_choice_list)
除了IntegrityError为e:
raise IntegrityError
return redirect(reverse('question-detail-view',kwargs = {'id':question.id}))

def question_detail(request,id) :
question_list = Question.objects.get(id = id)
return render(request,'question_detail.html',{'question_list':question_list})

urls.py

  url(r'^ question / $',new_question,name ='new-question-view'),
url(r'^ question /(?P< id> \d +)/ $' ,question_detail,name ='question-detail-view'),

如果要使用< a href =https://docs.djangoproject.com/en/1.9/ref/csrf/#ajax =nofollow> Ajax 提交而不是django表单sumbission 检查此 tutoriel


I am a newbie to Django and could not find similar questions after searching on google/SO.

I've a model named Questions, which has multiple(2-4) choices and defined as below:

class Question(models.Model):
  name = models.CharField(max_length=128)
class Choice(models.Model):
  name = models.CharField(max_length=256)     
  is_correct = models.BooleanField(default=False) 
  question = models.ForeignKey(Question, on_delete=models.CASCADE)

Of the multiple choices only one is correct.

What I want to do: In just one page, user could submit a question together with multiple choices, here is a draft of UI:

My first question: I've defined ModelForm but don't know how to add "choices" field to QuestionForm:

class QuestionForm(ModelForm):
  name = forms.CharField(max_length=128)
  description = forms.CharField(max_length=256)
  class Meta:
    model = Question
    fields = ['name', 'description']

class ChoiceForm(ModelForm):
  name = forms.CharField(max_length=256)
  is_correct = forms.BooleanField()
  class Meta:
    model = Choice
    fields = ['name', 'is_correct']

Is it possible to use ModelForm the render the above HTML page besides writing it manually?

My second question: If use clicks "Submit" button, I use AJAX to send json data to backend server, here is an example of form data:

name:question1
choices[][name]:choice1
choices[][is_correct]:1
choices[][name]:choice2
choices[][is_correct]:0

And this is my code handling the request:

form = QuestionForm(request.POST)
if form.is_valid():
  question = form.save()

How to parse choices from the request? How could I parse data of multiple choices part from the POST request?

Again, I'm a newbie to Django and any answers/suggestions is highly appreciated.

解决方案

You models seems to be correct, in order to be able to add mutiple choices in your template you need a formset. In addition you can put a formset and a form inside the same html form in a template and have them be validated individually. Each one only cares about the POST data relevant to them. Something like:

template.html

<form method="post" action="">
    {% csrf_token %}
    {{ choices_formset.management_form }} <!-- used by django to manage formsets -->
    {{ question_form.as_p }}
    {% for form in choices_formset %}
        {{ form.as_p }}
    {% endfor %}
  <button type='submit'>Submit</button>
</form>

views.py

from django.db import IntegrityError, transaction
from django.shortcuts import redirect
from django.forms.formsets import formset_factory
from django.core.urlresolvers import reverse

def new_question(request):
    ChoicesFormset = formset_factory(ChoicesForm)
    if request.method == 'POST':
        question_form = QuestionForm(request.POST)
        choices_formset = ChoicesFormset(request.POST)
        if question_form.is_valid():
            question = Question(**question_form.cleaned_data)
            if choices_formset.is_valid():
                question.save()
                new_choice_list = list()
                append_choice = new_choice_list.append
                for form in choices_formset:
                    form.cleaned_data.update({'question': question})
                    append_choice(Choice(**form.cleaned_data))
                try:
                    with transaction.atomic():
                        Choice.objects.bulk_create(new_choice_list)
                except IntegrityError as e:
                    raise IntegrityError
        return redirect(reverse('question-detail-view', kwargs={'id': question.id}))

def question_detail(request, id):
    question_list = Question.objects.get(id=id)
    return render(request, 'question_detail.html', {'question_list': question_list})

urls.py

url(r'^question/$', new_question, name='new-question-view'),
url(r'^question/(?P<id>\d+)/$', question_detail, name='question-detail-view'),

If you want to use rather Ajax submission rather than django form sumbission check this tutoriel.

这篇关于Django模型表单:显示OneToMany字段的查询表单和句柄请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆