我为我的db中的模型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/”)。我知道如何编写小部件,但我不知道如何将我的Movie模型中定义的掩码推送到此小部件。我不想违反DRY原则并在两个不同的地方定义这个面具。此外,它将成为与其他外部链接相同目的的良好工具。
您如何看待这个小部件?如何实现它?可能是有人在我面前写过它?
谢谢!
答案 0 :(得分:0)
所以,我决定不等待帮助并写下这个widget:
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)