2014-02-14 54 views
1

使用基於通用類CreateView的我試圖上傳通過ClearableFileInput部件是由inlineformset_factory使用的默認窗口小部件的圖像,但此未能保存圖像在Django。發行使用CreateView的和inlineformset_factory

的form.save()的作品就好在我看來,這似乎失敗specimage_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> 

我敢用新的基於類的意見,我設法與功能查看最後一次達致這,但他們似乎的老辦法做事情,有時這不是一個明顯的過渡。任何建議或指導將非常受歡迎。

謝謝。

回答

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的任何一個formset進行。

這兩種方法似乎工作正常。

有關綁定圖像以一種形式的詳細信息,在Django Docs

+0

近一週沒有評論,所以我接受這個答案。 – jayuu

相關問題