【发布时间】:2014-05-07 16:10:57
【问题描述】:
如何对用户指定的未知数量的字段执行 Django 表单验证?在我的例子中,表单允许用户创建包含任意数量曲目的音乐专辑并将其与艺术家相关联。该视图询问有多少轨道,然后生成一个包含那么多输入字段的表单。
表格:
class NumberOfTracks(forms.Form):
track_no = forms.IntegerField()
class CustomAlbumAdmin(forms.Form):
artist = forms.CharField(max_length=150)
album = forms.CharField(max_length=150)
track_no = forms.IntegerField()
track = forms.CharField(max_length=150)
查看:
def album_admin(request):
if request.GET.get('track_no'):
number_of_tracks = request.GET.get('track_no')
artists = Artist.objects.all()
return render(request, 'customadmin/album_admin1.html', {
'number_of_tracks': number_of_tracks,
'tracks': range(1, int(number_of_tracks) + 1),
'artists': artists,
})
elif request.method == 'POST':
form = CustomAlbumAdmin(request.POST)
print form
artist = request.POST['artist']
album = request.POST['album']
all_tracks = request.POST.getlist('track')
create_album = CreateAlbum(artist=artist, album=album, tracks=all_tracks)
create_album.save_album()
create_album.save_tracks()
form = NumberOfTracks()
return render(request, 'customadmin/no_tracks1.html', {
'form': form,
})
else:
form = NumberOfTracks()
return render(request, 'customadmin/no_tracks1.html', {
'form': form,
})
(很明显,我使用了if form.is_valid() 和form.cleaned_data,但到目前为止,为了使其正常工作,我不得不绕过它以获取原始 POST 数据)
让我感到困惑的部分原因是,我自定义了表单模板,根据用户输入添加了一个带有 name="track" 的数字输入字段(例如:创建一个包含 13 首曲目的专辑)。当我进入 print form = CustomAlbumAdmin(request.POST) 的视图时,它会根据我的形式给出一个非常简单的表格:一位艺术家、一张专辑、一首曲目和一首 track_no 因此验证这一点当然会返回 False 除非我有一张专辑只有一首曲目。
这是模板:
{% extends 'base.html' %}
{% block content %}
<form action="/customadmin/album1/" method="POST">{% csrf_token %}
<select name="artist">
{% for entry in artists %}
<option value="{{ entry.name }}">{{ entry.name }}</option>
{% endfor %}
</select>
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.album.errors }}
<label for="id_album">Album:</label>
<input id="id_album" maxlength="150" name="album" type="text" />
</div>
<div class="fieldWrapper">
{{ form.track.errors }}
<input type="hidden" name="number_of_tracks" value="{{ number_of_tracks }}">
{% for e in tracks %}
<label for="id_track">Track No. {{ forloop.counter }}</label>
<input id="id_track_{{ forloop.counter }}" maxlength="150" name="track" type="text" /></br>
{% endfor %}
</div>
<p><input type="submit" value="Save album" /></p>
</form>
{% endblock %}
我想解决这个问题的一种方法是创建一个自定义 clean_track 方法,该方法采用我在视图中使用all_tracks = request.POST.getlist('track') 完成的所有输入曲目的列表,但不知道如何做到这一点。
我的一个相关问题是我是否可以根据 POST 数据自定义验证。我解决这个问题的第一种方法是生成带有 name="track_1"、name="track_2" 等的递增输入。然后尝试基于此进行验证。但是,在这种情况下,我将无法使用request.POST.getlist('track')。
【问题讨论】:
标签: python django validation django-forms