I'll be as brief as possible.
我会尽量简短。
I want to able to do this
我想这样做
{{ video.youtube_url.video_id }}
by implementing something like the following custom field:
通过实现如下自定义字段:
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))
This:
这样的:
def _video_id(self):
return re.search('(?<=\?v\=)[\w-]+', self.value)
video_id = property(_video_id)
Does not sucessfully add a "video_id" attribute to my custom YouTubeURLField.
没有成功地向我的自定义YouTubeURLField添加“video_id”属性。
Everything else works flawlessly.
一切完美地工作。
I understand there maybe better design considerations in terms of the YouTube custom field, but I'd rather just understand, first, why this doesn't work.
我理解在YouTube自定义字段方面可能有更好的设计考虑,但我宁愿理解,首先,为什么它不能工作。
3 个解决方案
#1
2
Django fields are descriptors, which means that accessing them does not return the field, but rather the field value. You will need to override the Django field methods in order to return an object that has the attributes you care about, as well as a sanely-defined __unicode__()
method.
Django字段是描述符,这意味着访问它们并不返回字段,而是返回字段值。您将需要重写Django字段方法,以便返回一个具有您所关心的属性的对象,以及一个未定义的__unicode__()方法。
#2
0
Is there a reason you can't have it as a property of the model?
是否有理由不把它作为模型的属性?
In order to access data from an object not directly contained within the fields I frequently implement a pattern along the lines of:
为了从字段中不直接包含的对象访问数据,我经常按照以下方式实现一个模式:
class: Sheep(models.Model):
name = models.CharField(max_length=200)
@property
def sheep_says(self):
return "Baa... my name is %s ... baa" % self.name
Which you would then access in the template with:
然后,你可以在模板中使用:
{{ sheep.sheep_says }}
#3
0
I wanted to do it this way, because it seems it makes more sense from a design stand point. The video id is an attribute of the YouTube URL and not of the model itself.
我想这样做,因为从设计的角度来看它更有意义。视频id是YouTube URL的属性,而不是模型本身。
I figured it out. I overrode the to_python function to return a YouTubeURL object.
我想出来。我重写了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))
#1
2
Django fields are descriptors, which means that accessing them does not return the field, but rather the field value. You will need to override the Django field methods in order to return an object that has the attributes you care about, as well as a sanely-defined __unicode__()
method.
Django字段是描述符,这意味着访问它们并不返回字段,而是返回字段值。您将需要重写Django字段方法,以便返回一个具有您所关心的属性的对象,以及一个未定义的__unicode__()方法。
#2
0
Is there a reason you can't have it as a property of the model?
是否有理由不把它作为模型的属性?
In order to access data from an object not directly contained within the fields I frequently implement a pattern along the lines of:
为了从字段中不直接包含的对象访问数据,我经常按照以下方式实现一个模式:
class: Sheep(models.Model):
name = models.CharField(max_length=200)
@property
def sheep_says(self):
return "Baa... my name is %s ... baa" % self.name
Which you would then access in the template with:
然后,你可以在模板中使用:
{{ sheep.sheep_says }}
#3
0
I wanted to do it this way, because it seems it makes more sense from a design stand point. The video id is an attribute of the YouTube URL and not of the model itself.
我想这样做,因为从设计的角度来看它更有意义。视频id是YouTube URL的属性,而不是模型本身。
I figured it out. I overrode the to_python function to return a YouTubeURL object.
我想出来。我重写了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))