Django 迁移和可定制的可重用应用程序

2024-02-02

大约三周前,我开始编写我的第一个可重用应用程序,但我在处理迁移方面遇到了麻烦。

我希望我的应用程序的某些点是可定制的。因此我有一个conf子模块 https://github.com/Aladom/django-mailing/blob/6260556aa11128d6ecdb514b5a3fbd8c823fef60/mailing/conf.py定义自定义设置并分配适合大多数情况的合理默认值。

这导致我的一些模型字段看起来像这样:

attachment = models.FilePathField(
    path=conf.ATTACHMENTS_DIR, recursive=True)

template_file = models.FileField(
    upload_to=conf.TEMPLATES_UPLOAD_DIR, blank=True)

prefix_subject = models.BooleanField(
    default=True, verbose_name=_("prefix subject"),
    help_text=_(
        "Whether to prefix the subject with \"{}\" or not."
    ).format(conf.SUBJECT_PREFIX))

不幸的是,在使用此应用程序的项目中,这会导致django-admin makemigrations每次设置更改时为其创建迁移。或者甚至,他们第一次安装应用程序时,默认值取决于主机系统的设置。

我非常怀疑一个项目在他的应用程序副本中创建自己的迁移的合法性。但如果我错了,请告诉我。

For prefix_subject在上面的示例中,我解决了这个问题这个解决方案 https://stackoverflow.com/a/29233569/1529346。考虑到失去help_text移民方面的信息不是很有效。

但是,我不确定这是否适合所有/大多数情况。是吗?

我想到了另一个似乎有效的解决方案。此解决方案是手动编辑迁移并用变量本身替换评估的设置。

例如,我会替换这个:

migrations.CreateModel(
    name='MailStaticAttachment',
    fields=[
        ('id', ...),
        ('filename', ...)
        ('mime_type', ...)
        ('attachment', models.FilePathField(path='/home/antoine/Workspace/django-mailing/static/mailing/attachments', recursive=True, verbose_name='file')),
    ],
    options={...}
),

With :

from ..conf import ATTACHMENTS_DIR

migrations.CreateModel(
    name='MailStaticAttachment',
    fields=[
        ('id', ...),
        ('filename', ...)
        ('mime_type', ...)
        ('attachment', models.FilePathField(path=ATTACHMENTS_DIR, recursive=True, verbose_name='file')),
    ],
    options={...}
),

对您来说,这看起来是一个很好的解决方案吗?

在这种情况下,您建议做什么?

我认为两者Field.help_text, FilePathField.path and FileField.upload_to属性不用于创建 SQL 语句。所以在这种情况下,不应该因为“在迁移中忽略它们”而出现具体问题。但如果我假设想要一个可定制的Field.default, Field.db_column or CharField.max_length例如?这可能是一个非常糟糕的想法,没有实际利益,但这是我能找到的唯一假设情况。 :P 我想在这种情况下,最好提供一个抽象的基础模型,旨在由宿主项目进行扩展。


在设计过程中django.db.migration我们决定跟踪所有字段属性,即使它们不影响其模式表示。

For the upload_to我建议你简单地传递一个在模块级别定义的函数据记录 https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.FileField.upload_to.

import os

def upload_to(instance, filename):
    return os.path.join([conf.TEMPLATES_UPLOAD_DIR, filename])

For the path and help_text我建议你使用类似于我所做的方法django-sundial https://github.com/charettes/django-sundial/blob/2db2be7a2f1ae1f68bb3048ce98ec27b0259a1d8/sundial/zones.py#L40-L58提供可配置的默认值。你只需要确保传递一个类的实例deconstruct()返回适当参数的方法 https://docs.djangoproject.com/en/1.9/topics/migrations/#adding-a-deconstruct-method.

from django.utils.six import python_2_unicode_compatible


@python_2_unicode_compatible
class StringConfReference(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return getattr(conf, self.name)

    def deconstruct(self):
        return "%s.%s" % (__name__, self.__class__.__name__), (self.name,), {}


attachment = models.FilePathField(
    path=StringConfReference('ATTACHMENT_DIR'), recursive=True
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django 迁移和可定制的可重用应用程序 的相关文章

随机推荐