在 Django 中,可重复使用的模型成员可以帮助你减少代码重复并提高代码的可维护性和可扩展性。这些模型成员通常包括字段、方法、元选项和模型管理器等。

1、问题背景
在 Django 中拥有大量的可重复使用的模型成员(如字段、方法等),违反了 DRY 原则,导致代码冗余和难以维护。
2、解决方案
有以下几种解决方案:
- 使用抽象模型类 (Abstract Model):
创建一个抽象模型类,将可重用的字段和元选项放入其中,然后其他模型可以继承自该抽象模型类。适合于需要重用模型字段和元选项的情况。 
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;- 使用混合类 (Mixin Class):
创建一个混合类,将可重新使用的属性和方法放入其中,然后其他模型可以混入该混合类。适合于需要重用其他属性和方法的情况。 
class PhotoModelsMixin:
    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, PhotoModelsMixin):    
    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, PhotoModelsMixin):    
    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;- 使用子类化 (Subclassing):
创建一个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);class Something(models.Model): photo = ImageWithThumbnailField(upload_to=u'something')
这些解决方案都可以帮助您在 Django 中重用模型成员,从而减少代码冗余和提高维护性。在 Django 中,通过抽象基类、Mixin 类、自定义字段、管理器、元选项以及信号等方式,可以实现模型成员的复用。这些技术不仅减少了代码重复,还使得代码更加模块化和易操作。









