python – Django迁移和可定制的可重用应用程序
作者:互联网
我大约3周前开始编写我的第一个可重用的应用程序,而且我遇到了处理迁移的麻烦.
我希望我的应用程序的某些点可以自定义.因此,我有一个conf
submodule定义自定义设置并分配适合大多数情况的合理默认值.
这导致我的一些模型字段看起来像这样:
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在每次设置更改时为其创建迁移.甚至,他们第一次安装应用程序的设置默认值取决于主机系统.
我对在他的应用程序副本中创建自己的迁移的项目的合法性表示怀疑.但如果我错了,请告诉我.
对于上面示例中的prefix_subject,我解决了this solution的问题.考虑到在迁移中丢失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={...}
),
用:
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和FileField.upload_to属性都不用于创建SQL语句.因此,在这种情况下,由于“在迁移中忽略它们”,不应该存在具体问题.但是假设我想要一个可自定义的Field.default,Field.db_column或CharField.max_length呢?这可能是一个非常糟糕的想法,没有实际意义,但这是我能找到的唯一假设情况. :P我想在这种情况下,最好提供一个抽象基础模型,旨在由主机项目进行扩展.
解决方法:
在django.db.migration的设计过程中,决定跟踪所有字段属性,即使它们不影响它们的模式表示.
对于upload_to情况,我建议您只传递在模块级别as documented定义的函数.
import os
def upload_to(instance, filename):
return os.path.join([conf.TEMPLATES_UPLOAD_DIR, filename])
对于path和help_text,我建议你使用类似于我在django-sundial
中所做的方法来提供可配置的默认值.您只需要确保使用deconstruct()
method returning the appropriate parameters传递类的实例.
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
)
标签:python,django,django-apps,django-migrations 来源: https://codeday.me/bug/20190702/1355577.html