2012-04-05 20 views
10

Bunu dokümanlarda bulamadım, ancak bunun mümkün olduğunu düşünün. Ben özellikle ClearableFileInput widget'ından bahsediyorum. django 1.2.6 bir proje itibaren ben bu form var: i sonra bu şablon kodu kullanarak renderDjango'da bir widget'ın html çıktısını nasıl özelleştirebilirim?

# the profile picture upload form 
class ProfileImageUploadForm(forms.ModelForm): 
    """ 
    simple form for uploading an image. only a filefield is provided 
    """ 
    delete = forms.BooleanField(required=False,widget=forms.CheckboxInput()) 

    def save(self): 
     # some stuff here to check if "delete" is checked 
     # and then delete the file 
     # 8 lines 

    def is_valid(self): 
     # some more stuff here to make the form valid 
     # allthough the file input field is empty 
     # another 8 lines 

    class Meta: 
     model = SocialUserProfile 
     fields = ('image',) 

:

<form action="/profile/edit/" method="post" enctype="multipart/form-data"> 
    Delete your image: 
<label> {{ upload_form.delete }} Ok, delete </label> 
<button name="delete_image" type="submit" value="Save">Delete Image</button> 
    Or upload a new image: 
    {{ upload_form.image }} 
    <button name="upload_image" type="submit" value="Save">Start Upload</button> 
{% csrf_token %} 
</form> 

Django 1.3.1 artık varsayılan widget olarak ClearableFileInput kullandığı gibi, ben 'benim form.save 16 satırları atlamak ve sadece bu yüzden gibi formu kodunu kısaltabilir eminim: bana i az özelleştirilmiş formcode sahip iyi bir his verecek ve inci güvenebilirsiniz

# the profile picture upload form 
class ProfileImageUploadForm(forms.ModelForm): 
    """ 
    simple form for uploading an image. only a filefield is provided 
    """ 

    class Meta: 
     model = SocialUserProfile 
     fields = ('image',) 

e Django yerleşikleri.

Elbette html çıktısını eskisi gibi tutmak isterim. Sadece mevcut şablon kodunu kullandığınızda, "Şu anda: somefilename.png" gibi şeyler, onları istemediğim yerlerde açılır. FormField ayrıca, {{ upload_form.image.file }} gibi

Bölme çalışmak görünmüyor. Aklıma gelen bir sonraki şey özel bir widget yazmaktı. Tam olarak, olabildiğince çok sayıda özelleştirilmiş kodu kaldırma çabalarına tam olarak uyan.

Bu senaryoda yapılacak en basit şey ne olabilir?

+0

Kısa cevap: ADIM 1: Widget sınıfı ADIM 2 uzatmak: saha Not Widget geçersiz: İstediğiniz django formunun '__init__' yönteminde 1. adımda oluşturduğunuz alt sınıf widget'ını kullanmak için. Örneklere ihtiyacınız varsa, bana haber verin ve bu öğleden sonra vururum. –

+0

En son düşündüğüm, widget tarafından kullanılan şablonun geçersiz kılınmasıydı. Bu öğleden sonra ayarlayacağınız için minnettarım (tabii ki benden farklı bir kıtadasınız, işte burada olduğu gibi 16:15: D) – marue

+0

Evet, işten çıktığımda, size bir örnek vereceğim. ~ 5 saat kadar –

cevap

22

Öncelikle, bir uygulamadaki widgets.py dosyası oluşturun. Örneğim için, AdminFileWidget'u genişleten bir AdminImageWidget sınıfı yapacağım. Aslında, dosyanın yolunu vermek yerine, <img src="" /> etiketinde o anda yüklenen resmi gösteren bir resim yükleme alanı istiyorum.

sizin widgets.py dosyasında aşağıdaki sınıf koyun: Tamam, burada neler

from django.contrib.admin.widgets import AdminFileWidget 
from django.utils.translation import ugettext as _ 
from django.utils.safestring import mark_safe 
import os 
import Image 

class AdminImageWidget(AdminFileWidget): 
    def render(self, name, value, attrs=None): 
     output = [] 
     if value and getattr(value, "url", None): 

      image_url = value.url 
      file_name=str(value) 

      # defining the size 
      size='100x100' 
      x, y = [int(x) for x in size.split('x')] 
      try : 
       # defining the filename and the miniature filename 
       filehead, filetail = os.path.split(value.path) 
       basename, format  = os.path.splitext(filetail) 
       miniature     = basename + '_' + size + format 
       filename      = value.path 
       miniature_filename = os.path.join(filehead, miniature) 
       filehead, filetail = os.path.split(value.url) 
       miniature_url   = filehead + '/' + miniature 

       # make sure that the thumbnail is a version of the current original sized image 
       if os.path.exists(miniature_filename) and os.path.getmtime(filename) > os.path.getmtime(miniature_filename): 
        os.unlink(miniature_filename) 

       # if the image wasn't already resized, resize it 
       if not os.path.exists(miniature_filename): 
        image = Image.open(filename) 
        image.thumbnail([x, y], Image.ANTIALIAS) 
        try: 
         image.save(miniature_filename, image.format, quality=100, optimize=1) 
        except: 
         image.save(miniature_filename, image.format, quality=100) 

       output.append(u' <div><a href="%s" target="_blank"><img src="%s" alt="%s" /></a></div> %s ' % \ 
       (miniature_url, miniature_url, miniature_filename, _('Change:'))) 
      except: 
       pass 
     output.append(super(AdminFileWidget, self).render(name, value, attrs)) 
     return mark_safe(u''.join(output)) 

?

  1. Mevcut bir widget'ı içe (sıfırdan başlayarak olabilir, ama muhtemelen o ile başlayan buysa ClearableFileInput uzatmak mümkün olmalıdır) Ben sadece widget çıktı/sunum değiştirmek istiyorum
  2. altta yatan mantık değil. Yani, widget'ın render işlevini geçersiz kılıyorum. hale işlevinde
  3. Ben bunu yapmak gerekmez output = [] bir dizi olarak istediğiniz çıktıyı oluşturmak, ancak bazı birleştirme kaydeder. 3 önemli hatları:
    • output.append(u' <div><a href="%s" target="_blank"><img src="%s" alt="%s" /></a></div> %s ' % (miniature_url, miniature_url, miniature_filename, _('Change:'))) çıkışı
    • output.append(super(AdminFileWidget, self).render(name, value, attrs)) bir img etiketi ekler benim Widget'a ebeveynin çıkışını ekler
    • return mark_safe(u''.join(output)) boş dizeleri ile benim çıkış dizisi katılır VE gösterilmeden önce kaçmasını muaf

Bunu nasıl kullanırım?

class SomeModelForm(forms.ModelForm): 
    """Author Form""" 
    photo = forms.ImageField(
     widget = AdminImageWidget() 
    ) 

    class Meta: 
     model = SomeModel 

VEYA bize verdiği

class SomeModelForm(forms.ModelForm): 
    """Author Form""" 
    class Meta: 
     model = SomeModel 
     widgets = {'photo' : AdminImageWidget(),} 

:

admin screenshot

+2

Ugh, yaklaşık iki yıl sonra ve bu hala oy alıyor, lütfen özel yeniden boyutlandırma komut dosyaları ile bu gibi uygulamayın. SORL veya onun gibi bir şey kullanın. Ayrıca, bunun django depoları ile çalışmadığını lütfen unutmayın, sadece dosya sisteminde yazma/okuma yaptığınızı varsayar. –

+0

SORL? Otomobil Parçaları Şirketi? – CodyBugstein

+0

sorl thumbnail Kütüphane: http://sorl-thumbnail.readthedocs.org/en/latest/ –

İlgili konular