2010-12-02 89 views
2

我将尽可能简短。将属性添加到Django中的自定义字段

我希望能够通过执行类似下面的自定义字段要做到这一点

{{ 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) 

不成功地增加了“VIDEO_ID “属性到我的自定义YouTubeURLField。

其他一切完美无瑕。

我知道在YouTube自定义字段方面可能有更好的设计考虑,但我宁愿理解,首先,为什么这不起作用。

回答

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)) 
2

Django字段是descriptors,这意味着访问它们不会返回字段,而是字段值。您需要override the Django field methods才能返回具有您关心的属性的对象,以及明确定义的__unicode__()方法。

0

有没有理由让它不能作为模型的属性?

为了从没有直接包含的字段中的对象访问数据我经常实施的线沿线的一个模式:

{{ sheep.sheep_says }} 

class: Sheep(models.Model): 
    name = models.CharField(max_length=200) 

    @property 
    def sheep_says(self): 
     return "Baa... my name is %s ... baa" % self.name 

,你将在模板,然后访问

相关问题