简体   繁体   English

如何在 django 模型中动态创建属性方法?

[英]How to create property methods in django models dynamically?

I am creating property methods for every model where the model attribute includes ImageField or FileField.我正在为每个 model 创建属性方法,其中 model 属性包括 ImageField 或 FileField。 So, I decided to make an abstract model where I check the fields in the model and if there are any ImageField and FileField in the model the property method creates it automatically by itself.因此,我决定制作一个抽象的 model 来检查 model 中的字段,如果 model 中有任何 ImageField 和 FileField,该属性方法会自动创建它。

I usually add '_url' to the attribute when I create the method我通常在创建方法时将“_url”添加到属性中

Below is what I do usually下面是我通常做的

class MyModel(models.Model):
    image = ImageField(...)
    file = FileField(...)
    ...

    @property
    def image_url(self):
        if self.image and hasattr(self.image, 'url'):
            return self.image.url


    @property
    def file_url(self):
        if self.file and hasattr(self.file, 'url'):
            return self.file.url

    ...

Below what I did so far低于我到目前为止所做的

class MyModel(models.Model):
    ...
    

    def __new__(cls, value):
        fields = self._meta.get_fields()
        for field in fields:
            if isinstance(field, ImageField) or isinstance(field, FileField):
                ???

Any suggestions?有什么建议么?

Use mixins.使用混合。

class ImageUrlMixin:

    @property
    def image_url(self):
        if self.image and hasattr(self.image, "url"):
            return self.image.url

class FileUrlMixin:

    @property
    def file_url(self):
        if self.file and hasattr(self.file, "url"):
            return self.file.url

class FileImageUrlMixin(FileUrlMixin, ImageUrlMixin):
    pass

class OnlyHasFileFieldModel(FileUrlMixin, models.Model):
    # ..model implementation

class OnlyHasImageFieldModel(ImageUrlMixin, models.Model):
    # ..model implementation

class HasBothFileAndImageFieldModel(FileImageUrlMixin, models.Model):
    # ..model implementation

Or if you want to support fields dynamically eg my_model.arbitrary_field_url :或者,如果您想动态支持字段,例如my_model.arbitrary_field_url

class DynamicFieldUrlMixin:

    def __getattr__(self, name):
        if name.endswith("_url"):
            field_name = "".join(name.split("_")[:-1])
            field = getattr(self, field_name, None)
            if hasattr(field, "url"):
                return field.url
        raise AttributeError

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM