0

モデル Movie のフィールド imdb_id をデータベースに保持します。

class Movie(models.Model):
    imdb_id = models.IntegerField('imdb ID', blank=True, null=True, unique=True)

    def _get_imdb_url(self):
        return self.imdb_id and 'http://www.imdb.com/title/tt%s/' % str(self.imdb_id).zfill(7) or ''

    def _set_imdb_url(self, imdb_url):
        self.imdb_id = int( re.compile(r'[^\d]').sub('', imdb_url))

    imdb_url = property(_get_imdb_url, _set_imdb_url)

そして、フィールド 'imdb_id' のテキスト入力の近くの管理フォームに imdb.com への外部リンクを表示するための特別なウィジェットを作成したいと考えています。特別なマスク (私の場合、このマスクは ' http://www.imdb.com/title/tt%s/ ') を使用して生成された、外部リンクを持つ任意のフォーム フィールドのグローバル ウィジェットである可能性があると思います。ウィジェットの書き方は知っていますが、ムービー モデルで定義されたマスクをこのウィジェットにプッシュする方法がわかりません。DRY 原則に違反して、このマスクを 2 つの異なる場所で定義したくありません。また、将来的には他の外部リンクと同じ目的のための優れたツールになるでしょう。

このウィジェットについてどう思いますか? それを実現することはどのように可能ですか?誰かが私より前に書いたのだろうか?

ありがとう!

4

1 に答える 1

0

だから、私は助けを待たないことに決め、このウィジェットを書きました:

import re
from django import forms
class LinkFieldWidget(Widget):
    '''
    A TextField widget with previewing link, generated from field's value with special url mask
    '''
    def __init__(self, text, url='%s', *args, **kwargs):
        self.url = url
        self.text = text
        if not re.search('%', self.url):
            raise forms.ValidationError, u'Invalid URL mask'
        super(LinkFieldWidget, self).__init__(*args, **kwargs)

    def render(self, name, value, attrs=None):
        output = []
        output.append('''<input type="text" name="%s" value="%s" onkeyup="$('a#%s-link').attr('href', '%s'.replace('%s', this.value)).css({'display': (this.value ? 'inline' : 'none')})" />''' % (name, value or '', name, self.url, '%s'))
        if self.url and self.text:
            output.append('<span><a href="%s" id="%s-link" target="blank" style="display: %s;">%s</a></span>' % (value and self.url % value or '#', name, value and 'inline' or 'none', self.text))

        return mark_safe(u' '.join(output))

admin での使用例:

from utils.widgets import LinkFieldWidget
class MovieAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(MovieAdminForm, self).__init__(*args, **kwargs)
        self.fields['imdb_id'].widget = LinkFieldWidget(text='imdb', url=self.instance.imdb_link)

class MovieAdmin(admin.ModelAdmin):
    form = MovieAdminForm

モデル:

class Movie(models.Model):
    .....    
    imdb_link = 'http://www.imdb.com/title/tt%s/'
    def _get_imdb_url(self):
        return self.imdb_id and self.imdb_link % str(self.imdb_id).zfill(7) or ''
    def _set_imdb_url(self, imdb_url):
        self.imdb_id = int( re.compile(r'[^\d]').sub('', imdb_url))
    imdb_url = property(_get_imdb_url, _set_imdb_url)
于 2009-06-04T00:11:14.720 に答える