如何为照片网格创建 Django 表单?
How to create Django form for a photo grid?
我正在尝试创建一个包含一到十张照片的网格的 Django 表单。每张照片下方将有两个单选按钮组,一个用于指示查看者是批准还是拒绝该照片,第二组用于指示照片是否需要旋转。默认选中 "Approve" 和 "No" 单选按钮:
(photo1)
Approve or reject? Approve (x) Reject( )
Rotate? No (x) Left ( ) Right ( ) Flip ( )
(photo2)
Approve or reject? Approve (x) Reject( )
Rotate? No (x) Left ( ) Right ( ) Flip ( )
(more photos...)
当查看者提交表单时,我想检查每张照片的名称(例如"foobar.jpg")及其单选按钮,以确定它是被批准还是被拒绝以及是否需要轮换.照片名称都包含在 Python 列表中,我通过识别特定目录中的照片名称来填充该列表。
我不太明白如何在同一个表单中定义多个相同表单 "components"(在本例中为照片加单选按钮)的表单。我也不明白如何将照片名称合并到表格中以便显示照片。每张照片的名字都应该放在隐藏字段中吗?我在 Django 文档中没有看到任何解决这种情况的内容。
这似乎不是 Django Formsets 的工作。另外,我不想使用 ModelForms。感谢您的帮助。
以下是我的视图、表单和模板的缩写版本:
# views.py
def review_photos(request, template):
if request.method == "POST":
form = ReviewPhotosForm(request.POST) # Need another arg?
if form.is_valid():
# Extract each photo name and examine its corresponding radio buttons.
pass
else:
photo_names = list_all_files_in_dir("/path/to/photo/dir")
form = ReviewPhotosForm(photo_names=photo_names)
return render_to_response(template, locals(), context_instance=RequestContext(request))
# forms.py
class ReviewPhotosForm(forms.Form):
DECISION_CHOICES = ( ('approve', 'Approve'), ('reject', 'Reject') )
ROTATE_CHOICES = ( ('none,', 'None'), ('right', 'Right'), ('left', 'Left'), ('flip', 'Flip') )
def __init__(self, *args, **kwargs):
photo_names = kwargs.pop('photo_names')
super(ReviewPhotosForm, self).__init__(*args, **kwargs)
for name in photo_names:
self.fields[???] = forms.ChoiceField(
label = 'Approve or reject?',
choices = self.DECISION_CHOICES,
widget = forms.RadioSelect(renderer=widget.HorizontalRadioRenderer),
initial = 'approve')
self.fields[???] = forms.ChoiceField(
label = 'Rotate?',
choices = self.ROTATE_CHOICES,
widget = forms.RadioSelect(renderer=widget.HorizontalRadioRenderer),
initial = 'none')
# review_photos.html
<form action="." method="post">{% csrf_token %}
<ul>
<!-- How do I insert each photo's name into the form? -->
{% for field in form %}
<li>
<img src="{{ photo_name }}" /> <!-- ??? -->
<div id="decision">
{{ ???.label }}
{{ ??? }}
</div>
<div id="rotate">
{{ ???.label }}
{{ ??? }}
</div>
</li>
{% endfor %}
</ul>
<input type="submit" value="Submit" />
</form>
相反,这正是表单集的工作:'multiple identical form "components" all within the same form' 正是它们的本来面目。
class ReviewPhotosForm(forms.Form):
DECISION_CHOICES = ( ('approve', 'Approve'), ('reject', 'Reject') )
ROTATE_CHOICES = ( ('none,', 'None'), ('right', 'Right'), ('left', 'Left'), ('flip', 'Flip') )
# hidden field to associate radio buttons with a photo
photo_name = forms.CharField(widget=forms.HiddenInput)
approve = forms.ChoiceField(
label='Approve or reject?',
choices=self.DECISION_CHOICES,
widget=forms.RadioSelect(renderer=widget.HorizontalRadioRenderer),
initial='approve')
rotate = forms.ChoiceField(
label='Rotate?',
choices=self.ROTATE_CHOICES,
widget=forms.RadioSelect(renderer=widget.HorizontalRadioRenderer),
initial='none')
查看:
def review_photos(request, template):
ReviewPhotosFormSet = formset_factory(ReviewPhotosForm, extra=0)
if request.method == "POST":
formset = ReviewPhotosFormSet(request.POST)
if formset.is_valid():
# list of photos and radio buttons is in formset.cleaned_data
pass
else:
photo_names = list_all_files_in_dir("/path/to/photo/dir")
initial_data = [{'photo_name': name} for name in photo_names]
form = ReviewPhotosForm(initial=initial_data)
return render(request template, {'formset': formset})
模板:
<form action="." method="post">{% csrf_token %}
{{ formset.management_form }}
<ul>
{% for form in formset %}
<li> {{ form.photo_name }}
<img src="{{ form.photo_name.value }}" />
<div id="decision">
{{ form.decision.label_tag }}
{{ form.decision }}
{{ form.decision.errors }}
</div>
<div id="rotate">
{{ form.rotate.label_tag }}
{{ form.rotate }}
{{ form.rotate.errors }}
</div>
</li>
{% endfor %}
</ul>
</form>
我正在尝试创建一个包含一到十张照片的网格的 Django 表单。每张照片下方将有两个单选按钮组,一个用于指示查看者是批准还是拒绝该照片,第二组用于指示照片是否需要旋转。默认选中 "Approve" 和 "No" 单选按钮:
(photo1)
Approve or reject? Approve (x) Reject( )
Rotate? No (x) Left ( ) Right ( ) Flip ( )
(photo2)
Approve or reject? Approve (x) Reject( )
Rotate? No (x) Left ( ) Right ( ) Flip ( )
(more photos...)
当查看者提交表单时,我想检查每张照片的名称(例如"foobar.jpg")及其单选按钮,以确定它是被批准还是被拒绝以及是否需要轮换.照片名称都包含在 Python 列表中,我通过识别特定目录中的照片名称来填充该列表。
我不太明白如何在同一个表单中定义多个相同表单 "components"(在本例中为照片加单选按钮)的表单。我也不明白如何将照片名称合并到表格中以便显示照片。每张照片的名字都应该放在隐藏字段中吗?我在 Django 文档中没有看到任何解决这种情况的内容。
这似乎不是 Django Formsets 的工作。另外,我不想使用 ModelForms。感谢您的帮助。
以下是我的视图、表单和模板的缩写版本:
# views.py
def review_photos(request, template):
if request.method == "POST":
form = ReviewPhotosForm(request.POST) # Need another arg?
if form.is_valid():
# Extract each photo name and examine its corresponding radio buttons.
pass
else:
photo_names = list_all_files_in_dir("/path/to/photo/dir")
form = ReviewPhotosForm(photo_names=photo_names)
return render_to_response(template, locals(), context_instance=RequestContext(request))
# forms.py
class ReviewPhotosForm(forms.Form):
DECISION_CHOICES = ( ('approve', 'Approve'), ('reject', 'Reject') )
ROTATE_CHOICES = ( ('none,', 'None'), ('right', 'Right'), ('left', 'Left'), ('flip', 'Flip') )
def __init__(self, *args, **kwargs):
photo_names = kwargs.pop('photo_names')
super(ReviewPhotosForm, self).__init__(*args, **kwargs)
for name in photo_names:
self.fields[???] = forms.ChoiceField(
label = 'Approve or reject?',
choices = self.DECISION_CHOICES,
widget = forms.RadioSelect(renderer=widget.HorizontalRadioRenderer),
initial = 'approve')
self.fields[???] = forms.ChoiceField(
label = 'Rotate?',
choices = self.ROTATE_CHOICES,
widget = forms.RadioSelect(renderer=widget.HorizontalRadioRenderer),
initial = 'none')
# review_photos.html
<form action="." method="post">{% csrf_token %}
<ul>
<!-- How do I insert each photo's name into the form? -->
{% for field in form %}
<li>
<img src="{{ photo_name }}" /> <!-- ??? -->
<div id="decision">
{{ ???.label }}
{{ ??? }}
</div>
<div id="rotate">
{{ ???.label }}
{{ ??? }}
</div>
</li>
{% endfor %}
</ul>
<input type="submit" value="Submit" />
</form>
相反,这正是表单集的工作:'multiple identical form "components" all within the same form' 正是它们的本来面目。
class ReviewPhotosForm(forms.Form):
DECISION_CHOICES = ( ('approve', 'Approve'), ('reject', 'Reject') )
ROTATE_CHOICES = ( ('none,', 'None'), ('right', 'Right'), ('left', 'Left'), ('flip', 'Flip') )
# hidden field to associate radio buttons with a photo
photo_name = forms.CharField(widget=forms.HiddenInput)
approve = forms.ChoiceField(
label='Approve or reject?',
choices=self.DECISION_CHOICES,
widget=forms.RadioSelect(renderer=widget.HorizontalRadioRenderer),
initial='approve')
rotate = forms.ChoiceField(
label='Rotate?',
choices=self.ROTATE_CHOICES,
widget=forms.RadioSelect(renderer=widget.HorizontalRadioRenderer),
initial='none')
查看:
def review_photos(request, template):
ReviewPhotosFormSet = formset_factory(ReviewPhotosForm, extra=0)
if request.method == "POST":
formset = ReviewPhotosFormSet(request.POST)
if formset.is_valid():
# list of photos and radio buttons is in formset.cleaned_data
pass
else:
photo_names = list_all_files_in_dir("/path/to/photo/dir")
initial_data = [{'photo_name': name} for name in photo_names]
form = ReviewPhotosForm(initial=initial_data)
return render(request template, {'formset': formset})
模板:
<form action="." method="post">{% csrf_token %}
{{ formset.management_form }}
<ul>
{% for form in formset %}
<li> {{ form.photo_name }}
<img src="{{ form.photo_name.value }}" />
<div id="decision">
{{ form.decision.label_tag }}
{{ form.decision }}
{{ form.decision.errors }}
</div>
<div id="rotate">
{{ form.rotate.label_tag }}
{{ form.rotate }}
{{ form.rotate.errors }}
</div>
</li>
{% endfor %}
</ul>
</form>