django 中可重复使用的模型成员
我有一个像这样的 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;
我觉得这违反了 DRY,原因很明显。我的问题是,我可以将其粘贴到其他地方:
# ...
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'
# ...
然后用一行代码将其包含在相关模型类中吗?或者 photo_thumb 可以以某种方式动态添加到适当的类中吗?我尝试过经典继承和寄生继承,但我可能做得不对......我对 Django 很陌生,对 python 也很陌生。任何帮助表示赞赏。
I have a django model like this:
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;
I feel like this violates DRY, for obvious reasons. My question is, can I stick this somewhere 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'
# ...
And then include it in relevant model classes with a single line of code? Or can photo_thumb be dynamically added to the appropriate classes somehow? I've tried classical and parasitic inheritance, but I may not be doing it right... I'm new to Django and fairly new to python also. Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我同意@Gintautas 的观点。一般的经验法则是,如果您需要重用模型字段和元选项,则创建一个抽象模型类;如果您只需要重用其他属性和方法,请使用简单的类。
在你的情况下,我会选择抽象类(因为
photo
模型字段):...尽管这也是合法的:
I agree with @Gintautas. The general rule of thumb is to create an abstract model class if you need to reuse model fields and meta options; use a simple class if you only need to reuse other properties and methods.
In your case I'd go with the abstract class (because of the
photo
model field):... although this would be legal just as well:
另一个解决方案可能是创建
ImageField
的子类并覆盖contribute_to_class
方法:我认为这更好,因为在调用
photo_thumb
方法时,您可以期望self.photo
存在,如果您使用的是使用抽象模型的其他解决方案,则无法保证存在。编辑:请注意,您可以使用
getattr(self, name)
动态访问该字段。所以,是的,我们保证有一些照片字段。Another solution may be to create a subclass of
ImageField
and override thecontribute_to_class
method:I think this is better because on calling the
photo_thumb
method you are expecting the existence ofself.photo
which is not guaranteed if you are using the other solution that use an abstract model.EDIT: Note that you can use
getattr(self, name)
to dynamically access the field. So yes, it is guaranteed that we have some photo field.当然,您可以重用该代码。只需将其分解为基类,然后使两个类都继承自该基类即可。那应该可以正常工作。只是不要忘记基类需要从 models.Model 本身继承(那么我建议 使其抽象),或者你可以将可重用的代码放在 mixin 中;这意味着您的两个类都将从 models.Model 和新的 mixin 基类继承。
Sure you can reuse the code. Just factor it out into a base class, and make both your classes inherit from that base class. That should work just fine. Just don't forget that the base class either needs to inherit from models.Model itself (then I would suggest making it abstract), or you can put the reusable code in a mixin; that means that your both classes will be inheriting from both models.Model and the new mixin base class.
也许我问得太早了......我认为抽象基类可能是答案。
http://docs.djangoproject.com/en /dev/topics/db/models/#abstract-base-classes
我会检查并确认。
Maybe I asked too soon... I think abstract base classes may be the answer.
http://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes
I'll check it out and confirm.