2012-04-05 8 views
10

私はドキュメントでこれを見つけることができませんでしたが、可能でなければならないと思います。私はClearableFileInputウィジェットを具体的に話しています。ジャンゴ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> 

ジャンゴ1.3.1は、デフォルトのウィジェットとしてClearableFileInputを使用したように、I 「私は私のform.saveの16行をスキップし、ちょうどそうのようなフォームコードを短縮することができますかなり確信している:私は、私はあまりカスタマイズformcodeを持っている良い感じを与えるだろう、と目に頼ることができ

# 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ビルトイン。

もちろん、html出力を以前と同じように保つことができます。既存のテンプレートコードを使用するだけで、 "Currently:somefilename.png"のようなものは、私が望んでいない場所でポップアップします。

フォームフィールドをさらに分割すると、{{ upload_form.image.file }}のように動作しないようです。次に気になるのは、カスタムウィジェットを書くことでした。できるだけ多くのカスタマイズされたコードを削除しようとしている私の努力とは正反対です。

このシナリオで最も簡単なことは何ですか?

+0

短い答え:STEP 1:ウィジェットクラスSTEP 2を拡張:あなたのフィールドノート用のウィジェットを上書き:あなたが欲しいですdjangoフォームの '__init__'メソッドで、手順1で作成したサブクラス化ウィジェットを使用します。例が必要な場合は、私に知らせてください、そして、私は今日の午後にそれを打つでしょう。 –

+0

私が考えていた最新のことは、ウィジェットで使用されているテンプレートをオーバーライドすることだけです。あなたは今日の午後にチューニングしていただければ幸いです(私はあなたとは違う大陸にいるのは明らかです、ここではすべてが16:15:Dです) – marue

+0

うん、私は仕事を辞めて、 〜5またはそれ以上の時間 –

答えて

22

まず、アプリ内にwidgets.pyファイルを作成します。私の例では、を拡張するAdminImageWidgetクラスにします。基本的には、ファイルのパスを出力するのではなく、現在アップロードされている画像を<img src="" />タグで表示する画像アップロードフィールドが必要です。

は、あなたのwidgets.pyファイルに次のクラスを入れて:[OK]を、ので、ここで何が起こっているのか

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 = []これを行う必要はありませんが、いくつかの連結が保存されます。 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))は、空の文字列で私の出力配列を結合して表示
  4. 前に逃げることを免除

どうすれば使用できますか?

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

    class Meta: 
     model = SomeModel 

ORたちを与える

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

admin screenshot

+2

おおよそ2年後、これはまだ票を集めています。カスタムリサイズスクリプトをそのまま実装しないでください。 SORLなどを使用してください。また、これはdjangoのストレージでは機能しないことに注意してください。ちょうどあなたがファイルシステムで書き込み/読み込みを行っていると仮定します。 –

+0

SORL?自動車部品会社? – CodyBugstein

+0

sorlサムネイル:http://sorl-thumbnail.readthedocs.org/ja/latest/ –

関連する問題