2010-12-02 113 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 

,你將在模板,然後訪問

相關問題