2012-04-05 12 views
10

मुझे दस्तावेज़ों में यह नहीं मिला, लेकिन लगता है कि यह संभव होना चाहिए। मैं विशेष रूप से ClearableFileInput विजेट के बारे में बात कर रहा हूँ। Django 1.2.6 में एक परियोजना से मैं इस फार्म है:मैं Django में विजेट के HTML आउटपुट को कैसे अनुकूलित कर सकता हूं?

# 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 अब ClearableFileInput डिफ़ॉल्ट विजेट के रूप में उपयोग करता है, मैं 'यकीन है कि मैं अपने form.save के 16 लाइनों को छोड़ सकते हैं और सिर्फ इसलिए की तरह प्रपत्र कोड को छोटा हूँ:

# 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',) 

जो मुझे अच्छा लग रहा है मैं कम अनुकूलित formcode है देना होगा, और वें पर भरोसा कर सकते ई Django बिल्टिन।

मैं निश्चित रूप से एचटीएमएल आउटपुट को पहले जैसा रखना चाहता हूं। जब मौजूदा टेम्पलेट कोड का उपयोग करें, तो "वर्तमान में: somefilename.png" जैसी चीजें उन स्थानों पर पॉप अप करें जहां मैं उन्हें नहीं चाहता हूं।

फॉर्मफील्ड को आगे विभाजित करना, जैसे {{ upload_form.image.file }} काम नहीं कर रहा है। मेरे दिमाग में आने वाली अगली बात एक कस्टम विजेट लिखना था। जो संभवतः जितना संभव हो उतना अनुकूलित कोड हटाने के मेरे प्रयासों के खिलाफ काम करेगा।

कोई भी विचार इस परिदृश्य में क्या करना सबसे आसान बात होगी?

+0

संक्षिप्त उत्तर: चरण 1: विजेट वर्ग कदम 2 का विस्तार: के लिए अपने क्षेत्र नोट विजेट ओवरराइड: यदि आप चाहते django फॉर्म की '__init__' विधि में चरण 1 में बनाए गए उप-वर्गीकृत विजेट का उपयोग करने के लिए। अगर आपको उदाहरण की ज़रूरत है, तो मुझे बताएं और मैं इसे दोपहर मार दूंगा। –

+0

नवीनतम मैं विजेट के द्वारा उपयोग किए गए टेम्पलेट को ओवरराइड करने के बारे में सोच रहा था। इस दोपहर में आप ट्यूनिंग की सराहना करेंगे (आप स्पष्ट रूप से मेरे मुकाबले एक अलग महाद्वीप पर हैं, क्योंकि यहां यह पहले से ही है 16:15: डी) – marue

+0

हाँ जब मैं काम बंद कर देता हूं, बीमार आपको एक उदाहरण शूट करता है। ~ 5 या तो घंटे –

उत्तर

22

सबसे पहले, एक ऐप में widgets.py फ़ाइल बनाएं। मेरे उदाहरण के लिए, मैं आपको AdminImageWidget कक्षा बनाउंगा जो AdminFileWidget तक फैला है। अनिवार्य रूप से, मुझे एक छवि अपलोड फ़ील्ड चाहिए जो वर्तमान में अपलोड की गई छवि को फ़ाइल के पथ को आउटपुट करने के बजाय <img src="" /> टैग में दिखाता है।

अपने widgets.py फ़ाइल में निम्नलिखित वर्ग रखो:

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. मैं एक मौजूदा विजेट आयात (आप शुरू से आरंभ किया जा सकता है, लेकिन शायद ClearableFileInput विस्तार करने के लिए है कि अगर तुम क्या के साथ शुरू कर रहे हैं सक्षम होना चाहिए)
  2. मैं केवल विजेट के उत्पादन/प्रस्तुति को बदलना चाहते हैं अंतर्निहित तर्क नहीं। इसलिए, मैं विजेट के render फ़ंक्शन को ओवरराइड करता हूं।
  3. रेंडर फ़ंक्शन में मैं आउटपुट बनाता हूं जिसे मैं एक सरणी output = [] के रूप में चाहता हूं, आपको ऐसा करने की ज़रूरत नहीं है, लेकिन यह कुछ concatenation बचाता है। 3 प्रमुख लाइनों:
    • output.append(u' <div><a href="%s" target="_blank"><img src="%s" alt="%s" /></a></div> %s ' % (miniature_url, miniature_url, miniature_filename, _('Change:'))) उत्पादन
    • output.append(super(AdminFileWidget, self).render(name, value, attrs)) के लिए एक img टैग जोड़ता है मेरी विजेट के लिए माता-पिता की उत्पादन कहते हैं
    • return mark_safe(u''.join(output)) रिक्त स्ट्रिंग के साथ अपने उत्पादन सरणी जुड़ जाता है और प्रदर्शन से पहले भागने से यह छूट दी

मैं इसका उपयोग कैसे करूं?

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

    class Meta: 
     model = SomeModel 

या

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

कौन सा हमें देता है:

admin screenshot

+2

उह, लगभग दो साल बाद और यह अभी भी वोट प्राप्त कर रहा है, कृपया इसे अपनी कस्टम आकार बदलने वाली स्क्रिप्ट के साथ लागू न करें। एसओआरएल या इस तरह कुछ इस्तेमाल करें। साथ ही, कृपया ध्यान दें कि यह django स्टोरेज के साथ काम नहीं करता है, यह मानता है कि आप फाइल सिस्टम पर लिख रहे/पढ़ रहे हैं। –

+0

एसओआरएल? ऑटो पार्ट्स कंपनी? – CodyBugstein

+0

सॉर्ल थंबनेल लाइब्रेरी: http://sorl-thumbnail.readthedocs.org/en/latest/ –

संबंधित मुद्दे

 संबंधित मुद्दे