ユーザーがプロジェクトを作成できるアプリを作成しています。各プロジェクト内で、写真を関連付けることができる「場所」を作成できます。写真は、他の多くのタイプのモデルに関連付けることができる一般的なコンテンツモデルです。この場合、写真はすでにアップロードされており、プロジェクトに関連付けられています。ユーザーは、javascriptモーダルウィンドウを介して場所に関連付けるものを選択し、「メモ」を追加できます。
もともと私はこれを完全に手動で作成し、request.POSTを介してビューの写真にアクセスしました。ただし、メモのテキスト値に問題があったため、適切に実行して実際のモデルフォームセットを作成する方が簡単/優れていると判断しました。
フォームの.instance属性にアクセスすると、写真がテンプレートに表示されます。
これは正常に機能しています。写真やメモを追加したり、以前に追加したことがある場合は場所から削除したりできます。ただし、問題は、フォームに検証エラーがあり、ユーザーがそれらを処理するためにテンプレートに戻った場合、画像自体が表示されないことです。これは、フォームにインスタンス属性がアタッチされていないことが原因のようです。写真は、その場所にすでに保存されている写真のタグ(簡単なサムネイルを使用)を介して問題なく表示されます<img src="{{MEDIA_URL}}{{ photo.instance.photo.small.url }}">
が、追加/編集されたばかりの写真には表示されません。
私の質問は-この状況でどうすれば素敵なきれいな写真を表示できますか?
これが私のモデルフォームです:
class PhotoDisplayForm(ModelForm):
class Meta:
model = Photo
fields = {'id', 'note', }
widgets = {
'note': Textarea(attrs={'rows': 3}),
'photo': HiddenInput(),
'id': HiddenInput(),
}
views.py
def location_form(request, project_id, location_id=None):
project = Project.objects.get(id=project_id)
photos_formset = []
if location_id is None: #creates unbound forms
locPhotoFS = formset_factory(PhotoDisplayForm, max_num=0, can_delete=True)
photos_formset = locPhotoFS(prefix='loc_photos')
use_type = 'create' #this variable is passed to the template to display appropriate text
location_form = QuadratForm(request.POST or None, project_id=project_id)
else: ### edit an existing form ####
use_type = 'edit'
location = get_object_or_404(Location, pk=location_id)
location_form = QuadratForm(request.POST or None, project_id=project_id)
location_photos = Photo.objects.filter(location = location)
locPhotoFS = modelformset_factory(Photo, PhotoDisplayForm, max_num=0, can_delete=True)
photos_formset = locPhotoFS(queryset = location_photos, prefix='loc_photos')
if request.method == 'POST':
photos_formset = locPhotoFS(request.POST, prefix='loc_photos')
if location_form.is_valid() and photos_formset.is_valid():
location_instance = location_form.save(commit=False)
location_instance.project = get_object_or_404(Project, pk=project_id)
location_instance.save()
for form in photos_formset:
p = form.cleaned_data['id']
if form.cleaned_data['DELETE']:
p.content_object = project #reassociate the photo with the project
p.save()
else:
p.content_object = location_instance
p.note = form.cleaned_data['note'].strip()
print p.note
p.save()
return HttpResponseRedirect(reverse('core.views.location', args=(project_id, location_instance.id)))
else:
print 'there are errors'
context = {'location_type': location_type, 'use_type': use_type,'location_form': location_form,'project_photos': project.photos.all()}
if photos_formset:
context['photos_formset'] = photos_formset
return render(request, 'location_form.html', context)
レンプレート
{% if photos_formset %}
{% if location_form.non_field_errors %}{{ location_form.non_field_errors }}{% endif %}
{{ photos_formset.management_form }}
{% for photo in photos_formset %}
{% if photo.non_field_errors %}{{ photo.non_field_errors }}{% endif %}
<div class="photo-details original" id="{{photo.instance.id}}_photo-details">
<button type="button" photo="{{photo.instance.id}}" class="close pull-right photo-delete" aria-hidden="true">×</button>
<div class="photo-notes">{{ photo.note.label_tag }}{{ photo.note|attr:"class:photo_notes_input" }}{{ photo.errors }}</div>
{{ photo.id }}
{{ photo.DELETE|attr:"class:delete-photo" }}
<div class="thumbnail-caption">
<img src="{{MEDIA_URL}}{{ photo.instance.photo.small.url }}">
<br>{{ photo.instance.title }}
</div>
</div>
{% endfor %}
{% endif %}
役立つ場合は、写真モデル自体を次に示します。
class Photo(models.Model):
title = models.CharField(max_length=30)
photo = ThumbnailerImageField(upload_to=imagePath)
object_id = models.PositiveIntegerField()
content_type = models.ForeignKey(ContentType)
content_object = generic.GenericForeignKey('content_type', 'object_id')
note = models.TextField(max_length=200, blank=True)
def __unicode__(self):
return self.title