1

일반 클래스 기반 CreateView를 사용합니다. Inlineformset_factory에서 사용하는 기본 위젯 인 ClearableFileInput 위젯을 통해 이미지를 업로드하려고하는데 실패하고 있습니다.CreateView 및 inlineformset_factory를 사용하여 Django에서 이미지 저장 문제가 발생했습니다.

내 견해에서 form.save()가 제대로 작동하지만, 실패한 것으로 보이는 것은 specimenage_form.save()입니다. 제출하는 동안 self.request.FILES를 인쇄하면 선택된 파일이 메모리에있는 것처럼 보이지만 SpecImage save() 함수에서 print 문을 사용하면이 함수는 호출되지 않습니다. 어떤 조언이나 지침을 주셔서 감사합니다 -

내가 인쇄 문을 참조하는 경우 인라인을 사용하여 관리 사이트를 사용하여 이미지를 업로드 할 수 있습니다 ..

여기 내 코드입니다. 미리 감사드립니다 ..

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> 

나는 기능은 마지막 시간 전망이 acheive 관리 클래스를 기반으로보기에 아주 새로운 해요 그러나 그들은 이전 방법을 보인다 일을하고 때로는 명백한 전환이 아닙니다. 조언이나 안내는 대단히 환영 할 것입니다.

감사합니다.

답변

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

마찬가지로 ImageField가있는 formset에 대해 request.FILES에 대한 추가 참조를해야합니다.

두 접근 방식 모두 정상적으로 작동하는 것 같습니다.

이미지를 양식에 바인딩하는 방법에 대한 자세한 내용은 Django Docs입니다.

+0

거의 1 주일간 의견이 없으므로 답변으로 받아들입니다. – jayuu

관련 문제