代码之家  ›  专栏  ›  技术社区  ›  Dagg Nabbit

django的可恢复模型成员

  •  1
  • Dagg Nabbit  · 技术社区  · 15 年前

    我有这样一个django模型:

    class Something(models.Model):    
        title = models.CharField(max_length=200, default=u'')
        text  = models.CharField(max_length=250, default=u'', blank=True)
        photo = models.ImageField(upload_to=u'something')
        def photo_thumb(self):
            if self.photo:
                return u'<img src="%s" />' % (settings.MEDIA_URL + '/thumbs/?h=64&w=80&c=50x0&p=' + self.photo.name)
            else: 
                return u'(no photo)'
        photo_thumb.short_description = u'Photo'
        photo_thumb.allow_tags = True
        photo_thumb.admin_order_field = 'photo' 
        def __unicode__(self):
            return self.title;
    
    class SomethingElse(models.Model):    
        name = models.CharField(max_length=200, default=u'')
        foo  = models.CharField(max_length=250, default=u'', blank=True)
        photo = models.ImageField(upload_to=u'something_else')
        def photo_thumb(self):
            if self.photo:
                return u'<img src="%s" />' % (settings.MEDIA_URL + '/thumbs/?h=64&w=80&c=50x0&p=' + self.photo.name)
            else: 
                return u'(no photo)'
        photo_thumb.short_description = u'Photo'
        photo_thumb.allow_tags = True
        photo_thumb.admin_order_field = 'photo' 
        def __unicode__(self):
            return self.title;
    

    我觉得这是干的,原因很明显。我的问题是,我能把这个放在别的地方吗:

        # ...
        def photo_thumb(self):
            if self.photo:
                return u'<img src="%s" />' % (settings.MEDIA_URL + '/thumbs/?h=64&w=80&c=50x0&p=' + self.photo.name)
            else: 
                return u'(no photo)'
        photo_thumb.short_description = u'Photo'
        photo_thumb.allow_tags = True
        photo_thumb.admin_order_field = 'photo' 
        # ...
    

    然后用一行代码将其包含在相关的模型类中?或者可以通过某种方式动态地添加到相应的类中?我尝试过经典遗传和寄生遗传,但我可能做得不对。。。我对Django和python都很陌生。感谢您的帮助。

    4 回复  |  直到 15 年前
        1
  •  1
  •   satoru    15 年前

    另一种解决方案是创建 ImageField 并覆盖 contribute_to_class 方法:

    class ImageWithThumbnailField(ImageField):
        def contribute_to_class(self, cls, name):
            super(ImageWithThumbnailField, self).contribute_to_class(cls, name)
    
    
            def photo_thumb(self):
                photo = getattr(self, name, None)
                if photo:
                   return u'<img src="%s" />' % (settings.MEDIA_URL + '/thumbs/?h=64&w=80&c=50x0&p=' + photo.name)
                else: 
                   return u'(no photo)'
            photo_thumb.short_description = u'Photo'
            photo_thumb.allow_tags = True
            photo_thumb.admin_order_field = 'photo' 
    
            setattr(cls, 'photo_thumb', photo_thumb);
    

    photo_thumb 你所期待的方法的存在 self.photo

    编辑 :请注意,您可以使用 getattr(self, name) 动态访问字段。所以是的,我们有一些 照片 现场。

        2
  •  3
  •   Filip Dupanović    15 年前

    我同意金陶塔斯的说法。一般的经验法则是,如果需要重用模型字段和元选项,则创建一个抽象模型类;如果只需要重用其他属性和方法,则使用一个简单的类。

    photo 模型字段):

    class PhotoModels(models.Model):
    
        photo = models.ImageField(upload_to=u'something')
    
        def photo_thumb(self):
            if self.photo:
                return u'<img src="%s" />' % (settings.MEDIA_URL +
                       '/thumbs/?h=64&w=80&c=50x0&p=' + self.photo.name)
            else: 
                return u'(no photo)'
    
        photo_thumb.short_description = u'Photo'
        photo_thumb.allow_tags = True
        photo_thumb.admin_order_field = 'photo'
    
        class meta:
            abstract = True
    
    class Something(PhotoModels):    
        title = models.CharField(max_length=200, default=u'')
        text = models.CharField(max_length=250, default=u'', blank=True)
    
    class SomethingElse(PhotoModels):    
        name = models.CharField(max_length=200, default=u'')
        foo = models.CharField(max_length=250, default=u'', blank=True)
        photo.upload_to = u'something_else'
    
        def __unicode__(self):
            return self.title;
    

    class PhotoModels:
    
        def photo_thumb(self):
            if self.photo:
                return u'<img src="%s" />' % (settings.MEDIA_URL +
                       '/thumbs/?h=64&w=80&c=50x0&p=' + self.photo.name)
            else: 
                return u'(no photo)'
    
        photo_thumb.short_description = u'Photo'
        photo_thumb.allow_tags = True
        photo_thumb.admin_order_field = 'photo' 
    
    class Something(models.Model, PhotoModels):    
        title = models.CharField(max_length=200, default=u'')
        text = models.CharField(max_length=250, default=u'', blank=True)
        photo = models.ImageField(upload_to=u'something')
    
    class SomethingElse(models.Model, PhotoModels):    
        name = models.CharField(max_length=200, default=u'')
        foo = models.CharField(max_length=250, default=u'', blank=True)
        photo = models.ImageField(upload_to=u'something_else')
    
        def __unicode__(self):
            return self.title;
    
        3
  •  1
  •   Gintautas Miliauskas    15 年前

    当然你可以重用代码。把它分解成一个基类,让两个类都继承这个基类。那应该很管用。只是别忘了基类需要从模型。模型本身(那么我建议 making it abstract 新的mixin基类。