我正在构建一个用户可以创建项目的应用程序;在每个项目中,他们可以创建可以关联照片的“位置”。Photo 是一种通用的内容模型,可以与许多其他类型的模型相关联。在这种情况下,照片已经上传并与项目相关联。用户可以通过 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(),
}
视图.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