1

Использование Generic CreateView на основе классов Я пытаюсь загрузить изображение через виджет ClearableFileInput, который является виджлером по умолчанию, используемым inlineformset_factory, но это не работает.Проблема с сохранением изображения в Django с использованием CreateView и inlineformset_factory

Форма.save() работает очень хорошо, на мой взгляд, это образец sample_form.save(), который, кажется, терпит неудачу. Если я распечатываю self.request.FILES во время представления, он выглядит так, как будто выбранный файл находится в памяти, - но приклеивая инструкцию печати в функции SpecImage save(), становится ясно, что эта функция никогда не вызывается.

можно загрузить изображение с помощью сайта администратора с помощью Внутристрочные в этом случае я вижу оператор печати ..

Вот мой код - признателен за любые советы или рекомендации. Заранее спасибо ..

models.py

class Spec(models.Model): 
    car = models.ForeignKey('vehicles_dvla_listpoint.AutoLookup') 
    owner = models.ForeignKey(User) 
    uploaded = models.DateField(default=date.today, editable=False) 

    def get_absolute_url(self): 
     return reverse('car_create') 

    def __unicode__(self): 
     return "{0}".format(self.car) 

class SpecImage(models.Model): 
    def orig_car_id_folder(instance, filename): 
     return 'uploads/images/orig/{0}/{1}'.format(instance.car_id, filename) 
    def thumb_car_id_folder(instance, filename): 
     return 'uploads/images/thumb/{0}/{1}'.format(instance.car_id, filename) 

    car = models.ForeignKey(Spec) 

    orig_image = models.ImageField(
     upload_to=orig_car_id_folder, 
     verbose_name='Upload Image', 
    ) 

    thumbnail = models.ImageField(
     upload_to=thumb_car_id_folder, 
     null=True, 
     blank=True, 
    ) 

    def save(self, force_update=False, force_insert=False): 
     print "here ...." # << Don't see this where submitting outside of the admin 
     import os 
     from PIL import Image 
     from cStringIO import StringIO 
     from django.core.files.uploadedfile import SimpleUploadedFile 
     # Set thumbnail size 
     THUMBNAIL_SIZE = (75, 75) 
     # Process original image using PIL 
     image = Image.open(self.orig_image)   
     # Convert to RGB if necessary 
     if image.mode not in ('L', 'RGB'): 
      image = image.convert('RGB') 
     # PIL already has constraint proportions 
     # Also use Image.ANTIALIAS to make the image look better 
     image.thumbnail(THUMBNAIL_SIZE, Image.ANTIALIAS) 
     # Save thumbnail - to disk? 
     temp_handle = StringIO() 
     image.save(temp_handle, 'png') 
     temp_handle.seek(0) 
     # Save to thumbnail field (in table) 
     # Prepare file name - just name & strip .ext 
     name_ext = os.path.splitext(os.path.split(self.orig_image.name)[-1]) 
     suf = SimpleUploadedFile(name_ext[0], 
       temp_handle.read(), content_type='image/png') 
     self.thumbnail.save(suf.name+'.png', suf, save=False) 
     # Save this photo instance (again) 
     super(SpecImage, self).save() 

urls.py

urlpatterns = patterns('', 
    url(r'^add/$', CarCreate.as_view(), name='car_create'), 
    url(r'^thanks/$', TemplateView.as_view(template_name='thanks.html')), 
) 

forms.py

import autocomplete_light 
from django.forms.models import inlineformset_factory 

from .models import Spec, SpecImage 

class SpecForm(autocomplete_light.ModelForm): 
    class Meta: 
     model = Spec 

SpecImageFormSet = inlineformset_factory(Spec, SpecImage, extra=1) 

views.py

class CarCreate(CreateView): 
    template_name = 'spec_form_inlines.html' 
    model = Spec 
    form_class = SpecForm 
    success_url = '/car/thanks/' 

    def form_valid(self, form): 
     context = self.get_context_data() 
     specimage_form = context['specimage_form'] 
     if specimage_form.is_valid(): 
      self.object = form.save() 
      specimage_form.instance = self.object 
#   specimage_form.instance = self.request.FILES 
      specimage_form.save() 
      return HttpResponseRedirect('/car/thanks/') 
     else: 
      return self.render_to_response(self.get_context_data(form=form)) 

    def form_invalid(self, form): 
     return self.render_to_response(self.get_context_data(form=form)) 

    def get_context_data(self, **kwargs): 
     context = super(CarCreate, self).get_context_data(**kwargs) 
     if self.request.POST: 
      context['specimage_form'] = SpecImageFormSet(self.request.POST) 
     else: 
      context['specimage_form'] = SpecImageFormSet() 
    return context 

spec_form_inlines.html

<html> 
<body> 

<h1>Add Book</h1> 

<form enctype="multipart/form-data" method="post" action=""> 
    {% csrf_token %} 

    {{ form.as_p }} 

    {{ specimage_form.management_form }} 
    {% for form in specimage_form.forms %} 
     {{ form.as_p }} 
    {% endfor %} 

    <input type="submit" value="Add Car" class="submit"/> 
</form> 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.js" type="text/javascript"></script> 
{% include 'autocomplete_light/static.html' %} 

</body> 
</html> 

Я довольно новое с Основываясь Просмотры класса мне удалось добиться этого с функцией видит в последний раз, но они, кажется, старый способ делая вещи, и иногда это не очевидный переход. Любые советы или рекомендации были бы очень желанными.

Спасибо.

ответ

5

Так что это кажется довольно простым исправлением, но мне потребовалось некоторое время, чтобы решить проблему, проверив онлайн-примеры и прочитав документы Django, поэтому я оставляю их здесь, а не снимаю вопрос.

Мой первоначальный код был основан на this blog post.

Если я что-то не упустил, несмотря на то, что я был примером, включающим загрузку изображения, то, что, по-видимому, отсутствует, является ссылкой на request.FILES для привязки изображений. Таким образом, простое изменение, внесенное которое теперь, кажется, работает, чтобы изменить эту строку:

if self.request.POST: 
    context['specimage_form'] = SpecImageFormSet(self.request.POST) 

этой

if self.request.POST: 
    context['specimage_form'] = SpecImageFormSet(self.request.POST, self.request.FILES) 

Дополнительный пример, который использует render_to_response вместо установки контекста элемента можно найти here

Аналогично, дополнительная ссылка на request.FILES должна быть сделана в зависимости от того, какой набор форм имеет ImageField.

Оба этих подхода, похоже, работают нормально.

Дополнительная информация о привязке изображений к форме находится в Django Docs.

+0

Нет комментариев в течение почти недели, поэтому я принимаю это как ответ. – jayuu