为啥 Django makemigrations 每次运行时都会检测到由于 help_text/verbose_name 属性中的重音而导致的更改?
Posted
技术标签:
【中文标题】为啥 Django makemigrations 每次运行时都会检测到由于 help_text/verbose_name 属性中的重音而导致的更改?【英文标题】:Why Django makemigrations detect changes everytime it is run due to accent in help_text/verbose_name attributes?为什么 Django makemigrations 每次运行时都会检测到由于 help_text/verbose_name 属性中的重音而导致的更改? 【发布时间】:2015-12-06 20:05:24 【问题描述】:我正在使用Python-2.7
并在help_text
或verbose_name
属性中获得了一个带有法语字符串(即 重音)的models.py 文件。
models.py
完成models.py is available as a gist。摘录如下:
# -*- coding: utf-8 -*-
class Checkpoint(models.Model):
name = models.CharField(max_length=128, help_text=_('Nom du repère/checkpoint'))
passed = models.BooleanField(default=False, help_text=_('Le checkpoint a t-il était validé?'))
site = models.ForeignKey('Site', null=True, help_text=_('Entité concernée par le checkpoint'))
def __unicode__(self):
return u'%s' % self.name
manage.py makemigrations
每次我运行 ./manage.py makemigrations
时,我都会得到一个 AlterField
用于所有模型字段的重音字符:
migrations.AlterField(
model_name='checkpoint',
name='name',
field=models.CharField(help_text='Nom du rep\xe8re/checkpoint', max_length=128),
),
试用 #1:将 é
和其他替换为反斜杠等效的 \xe9
我明白了:
Traceback (most recent call last):
File "/home/elopez/apps/pycharm-4.5.2/helpers/pycharm/django_manage.py", line 41, in <module>
run_module(manage_file, None, '__main__', True)
File "/usr/lib/python2.7/runpy.py", line 176, in run_module
fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 82, in _run_module_code
mod_name, mod_fname, mod_loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/home/elopez/projects/evrpa/manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/core/management/base.py", line 393, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/core/management/base.py", line 444, in execute
output = self.handle(*args, **options)
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 125, in handle
migration_name=self.migration_name,
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/db/migrations/autodetector.py", line 43, in changes
changes = self._detect_changes(convert_apps, graph)
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/db/migrations/autodetector.py", line 186, in _detect_changes
self.generate_altered_fields()
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/db/migrations/autodetector.py", line 850, in generate_altered_fields
if old_field_dec != new_field_dec:
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/utils/functional.py", line 165, in __eq__
return self.__cast() == other
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/utils/functional.py", line 151, in __cast
return self.__bytes_cast()
File "/home/elopez/.env/evrpa/local/lib/python2.7/site-packages/django/utils/functional.py", line 144, in __bytes_cast
return bytes(func(*self.__args, **self.__kw))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe8' in position 10: ordinal not in range(128)
试用 #1:将字符串标记为带有 u
前缀的 unicode
给出同样的错误
问题
如何防止 Django 迁移以检测那些误报修改?
【问题讨论】:
【参考方案1】:建议help_text
和verbose_name
使用unicode 字符串。
尝试使用 u
前缀将字符串标记为 unicode,然后找到之前将详细名称设置为字节字符串的迁移,并将其也更改为 unicode 字符串。由于编辑 help_text
和 verbose_name
不需要任何架构更改,因此这样做应该是安全的。
migrations.AddField(
model_name='datedmodel',
name='created',
field=models.DateTimeField(default=datetime.datetime(2015, 9, 10, 14, 8, 23, 349990, tzinfo=utc), verbose_name='Créé le', auto_now_add=True),
preserve_default=False,
),
迁移文件中不需要 u'' 前缀,因为它有 from __future__ import unicode_literals
。
然后,当您重新运行 makemigrations
时,Django 会很有希望地说“未检测到更改”。
【讨论】:
help_text
和 verbose_name
前缀+编辑迁移都没有解决问题
我仍然认为将help_text
和verbose_name
名称切换到unicode 是正确的方法。看看 Django 应用程序,例如auth models。他们使用from __future__ import unicode_literals
,因此所有帮助字符串和详细名称都是unicode。必须将encode('utf-8')
添加到您的字符串中感觉非常脆弱。仅仅因为它没有解决您的问题而拒绝我的回答不会鼓励我再为您提供帮助。希望你能解决你的问题。
您编辑了问题以关注verbose_name
,而忽略了我的问题在于help_text
这一事实。无论如何,我承认-1
有点苛刻,但你最后的评论比你的回答更有意义
我编辑了这个问题,因为你最初的问题中的代码根本没有使用 help_text,它不是为了冒犯你。
在顶部添加from __future__ import unicode_literals
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe8' in position 10: ordinal not in range(128)
makemigrations
【参考方案2】:
附加.encode('utf-8')
可以防止错误,但makemigrations
仍然会在每次运行时检测到更改。
class Checkpoint(models.Model):
name = models.CharField(max_length=128, help_text=_('Nom du repère/checkpoint'.encode('utf-8')))
passed = models.BooleanField(default=False, help_text=_('Le checkpoint a t-il était validé?'.encode('utf-8')))
site = models.ForeignKey('Site', null=True, help_text=_('Entité concernée par le checkpoint'.encode('utf-8')))
【讨论】:
以上是关于为啥 Django makemigrations 每次运行时都会检测到由于 help_text/verbose_name 属性中的重音而导致的更改?的主要内容,如果未能解决你的问题,请参考以下文章
Django 1.7 - makemigrations 为非托管模型创建迁移
Django 1.8 - migrate 和 makemigrations 有啥区别?
Django 1.7 makemigrations 没有效果
Django Makemigrations 和 Migrate 不断重复
Django 上的 MakeMigration 错误 - ImportError:无法从“django.db.models”导入名称“FieldDoesNotExist”