フォームセットを使用して画像をアップロードし、多対多の関係を使用してモデルにリンクしています。ステータス フォームの下にフォームセットを表示して、ユーザーがステータス フィールドに入力し、画像を追加してから、[保存] または [別の画像を保存して追加] をクリックします。
最後のケースでは、事前に入力されたステータス フォームを表示し、フォームセット内に、アップロードされたファイルを処理するための通常のものを含むブロック (画像へのリンク、削除するチェックボックス、別の画像をアップロードするためのファイル入力) を表示する必要があります。最後に、2 番目の画像をアップロードするための空のファイルを入力します。現在、2 つの空のファイルを入力しています。
フォームセットは、既に 1 つの画像がアップロードされていることを認識していますが、それを管理するために何も表示しません。これはフォームセットの ImageField の通常の動作ですか、それともフォームセット データを提供する方法に問題がありますか?
コードは次のとおりです。
# Models
class Image(models.Model):
image = ImageField(upload_to='uploads/status/images/',)
class Status(models.Model):
author = models.ForeignKey(User,)
images = models.ManyToManyField(Image, blank=True, null=True)
body = models.TextField()
# Forms
class StatusForm(forms.ModelForm):
class Meta:
model = Status
fields = ['body',]
class ImageForm(forms.ModelForm):
class Meta:
model = Image
fields = ['image',]
# View
@csrf_protect
def form(request, id=None, template_name='status/form.html'):
if id:
status = get_object_or_404(Status, pk=id)
images = status.images.all().values()
else:
status = Status(author=request.user)
images = None
if request.method == 'POST':
form = StatusForm(request.POST, instance=status)
formset = ImageFormSet(request.POST, request.FILES, initial=images)
if form.is_valid():
try:
status = form.save()
if formset.is_valid():
try:
for form in formset:
image = form.save()
status.images.add(image)
status.save()
if request.POST.get('_add_image', None):
return HttpResponseRedirect(reverse('status_edit', args=[status.id]))
else:
messages.success(request, 'Status saved')
return HttpResponseRedirect(request.POST.get('next', '/'))
except:
messages.error(request, 'Technical error')
except:
messages.error(request, 'Technical error')
else:
form = StatusForm(instance=status)
formset = ImageFormSet(initial=images)
return render_to_response(template_name, {
'form': form,
'formset': formset,
'next': request.GET.get('next', '/'),
}, context_instance=RequestContext(request))
テンプレート:
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.non_field_errors }}
<input type="hidden" name="next" value="{{ next }}" />
{{ form.body }}
{{ form.body.errors }}
<hr />
{{ formset }}
<hr />
<div class="pull-right">
<input name="_add_image" class="btn" type="submit" value="Add another image">
<input name="_complete" class="btn btn-primary" type="submit" value="Save">
</div>
</form>