我会尽可能简短。
我希望能够做到这一点
{{ video.youtube_url.video_id }}
通过实现以下自定义字段:
class YouTubeURLField(URLField):
description = _("YouTubeURL")
def _video_id(self):
return re.search('(?<=\?v\=)[\w-]+', self.value)
video_id = property(_video_id)
def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
super(YouTubeURLField, self).__init__(**kwargs)
kwargs['max_length'] = kwargs.get('max_length', 200)
CharField.__init__(self, verbose_name, name, **kwargs)
self.validators.append(YouTubeURLValidator(verify_exists=verify_exists))
此:
def _video_id(self):
return re.search('(?<=\?v\=)[\w-]+', self.value)
video_id = property(_video_id)
未成功向我的自定义YouTubeURLField添加“video_id”属性。
其他一切都完美无缺。
我理解在YouTube自定义字段方面可能有更好的设计考虑因素,但我宁愿理解,首先,为什么这不起作用。
答案 0 :(得分:2)
Django字段是descriptors,这意味着访问它们不会返回字段,而是返回字段值。您需要override the Django field methods才能返回具有您关注的属性的对象,以及明确定义的__unicode__()
方法。
答案 1 :(得分:0)
是否有理由不能将其作为模型的属性?
为了从不直接包含在字段中的对象访问数据,我经常按照以下方式实现模式:
class: Sheep(models.Model):
name = models.CharField(max_length=200)
@property
def sheep_says(self):
return "Baa... my name is %s ... baa" % self.name
然后您将在模板中访问:
{{ sheep.sheep_says }}
答案 2 :(得分:0)
我想这样做,因为从设计角度看它似乎更有意义。视频ID是YouTube网址的属性,而不是模型本身的属性。
我明白了。我重写了to_python函数以返回一个YouTubeURL对象。
class YouTubeURL(object):
def __init__(self, value):
self.value = value
@property
def video_id(self):
regex = re.compile(r'/v/([A-Za-z0-9\-_]+)', re.IGNORECASE)
id = regex.search(self.value)
return id.group(1)
def __unicode__(self):
return "%s" % (self.value,)
def __str__(self):
return "%s" % (self.value,)
def __len__(self):
return len(self.value)
class YouTubeURLField(URLField):
description = _("YouTubeURL")
__metaclass__ = SubfieldBase
def to_python(self, value):
return YouTubeURL(value)
def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
super(YouTubeURLField, self).__init__(**kwargs)
kwargs['max_length'] = kwargs.get('max_length', 200)
CharField.__init__(self, verbose_name, name, **kwargs)
self.validators.append(YouTubeURLValidator(verify_exists=verify_exists))