У меня есть листинговая модель и фотомодель:
class Listing(models.Model):
title = models.CharField(max_length=255)
<more fields>...
class Photo(models.Model):
image = models.ImageField(upload_to=create_file_path)
listing = models.ForeignKey(Listing, related_name='photos')
Я использую CBV, UpdateView, для редактирования листинга. Я использую эту форму:
class ListingDetailForm(forms.ModelForm):
class Meta:
model = Listing
exclude = []
и встроенный набор форм в forms.py, чтобы сделать возможным удаление/изменение изображения:
PhotoFormset = inlineformset_factory(Listing, Photo, fields='__all__', extra=1)
вот мой взгляд:
class ListingDetailView(UpdateView):
model = Listing
template_name = 'listing/listing_detail.html'
form_class = ListingDetailForm
success_url = '/store/'
def get_context_data(self, **kwargs):
self.object = self.get_object()
context = super(ListingDetailView, self).get_context_data(**kwargs)
if self.request.POST:
context['form'] = ListingDetailForm(self.request.POST, instance=self.object)
context['photo_form'] = PhotoFormset(self.request.POST, self.request.FILES, instance=self.object)
else:
context['form'] = ListingDetailForm(instance=self.object)
context['photo_form'] = PhotoFormset(instance=self.object)
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
photo_form = PhotoFormset(self.request.POST)
print photo_form.is_valid()
if form.is_valid() and photo_form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
print 'in form valid for update'
context = self.get_context_data()
base_form = context['form']
photo_form = context['photo_form']
# print base_form
# print photo_form
if base_form.is_valid() and photo_form.is_valid():
print 'forms are valid for update'
base_form.save()
photo_form.save()
return super(ListingDetailView, self).form_valid(form)
else:
return self.render_to_response(self)
и соответствующий раздел шаблона:
{% block body %}
<form action="" method="post">
{% csrf_token %}
{% for field in form %}
{{ field.errors }}
{{ field.label_tag }} {{ field }}<br><br>
{% endfor %}
{% for field in photo_form %}
{{ field.errors }}
{{ field.label_tag }} {{ field }}<br><br>
{% endfor %}
{{ photo_form.management_form }}
<input type="submit" value="Update" />
</form>
{% endblock %}
Проблемы, которые у меня возникают:
1) Если к объявлению прикреплена фотография, через админку фотоформа не проходит валидацию, если я ничего не делаю с фотоформой, т.е. изменить только поля из модели листинга. Форма фото не отображает ошибок, когда страница перезагружается после недействительного.
2) выбор новой фотографии не меняет текущую фотографию, форма фотографии не проверяется и не отображает ошибок.
3) если в настоящее время нет фотографии, относящейся к списку, попытка добавить одну проверяет через форму, но фактически не сохраняет фотографию, связанную с этим списком.
Удаление изображения, если оно прикреплено к листингу, работает отлично. Удаление изображения и обновление какого-либо другого поля из списка работает. Если нет обновления изображения, работает только поле списка. Добавление второй фотографии в список через форму не работает и не выводит ошибок формы.