Aka*_*007 9 django django-migrations
我有一个从django片段复制的base64字段.
https://djangosnippets.org/snippets/1669/
class Base64Field(models.TextField):
"""
https://djangosnippets.org/snippets/1669/
Example use:
class Foo(models.Model):
data = Base64Field()
foo = Foo()
foo.data = 'Hello world!'
print foo.data # will 'Hello world!'
print foo.data_base64 # will print 'SGVsbG8gd29ybGQh\n'
"""
def contribute_to_class(self, cls, name):
if not self.db_column:
self.db_column = name
self.field_name =name+ '_base64'
super(Base64Field, self).contribute_to_class(cls, self.field_name)
setattr(cls, name, property(self.get_data, self.set_data))
def get_data(self, obj):
return base64.decodestring(getattr(obj, self.field_name))
def set_data(self, obj, data):
setattr(obj, self.field_name, base64.encodestring(data))
def deconstruct(self):
ame, path, args, kwargs = super(Base64Field, self).deconstruct()
from pprint import pprint
pprint(vars(self))
return ame, path, args, kwargs
Run Code Online (Sandbox Code Playgroud)
我在迁移这个领域时遇到了问题,例如
class EmailStatus(models.Model):
attachment = Base64Field(null=True, blank=True, db_column='attachment', name="attachment", verbose_name="attachment")
Run Code Online (Sandbox Code Playgroud)
我在迁移时遇到的错误是
raise FieldDoesNotExist('%s has no field named %r' % (self.object_name, field_name))
Run Code Online (Sandbox Code Playgroud)
django.core.exceptions.FieldDoesNotExist: EmailStatus has no field named u'attachment'
现在我可以看到为什么会这样.但是无法找到解决方法.我想我可能需要在解构领域改变一些东西.我为此尝试过多种方法,但所有这些都破了.
例如删除_base64.保存和检索数据时,它不起作用.
我尝试更改迁移文件中的名称,但它不起作用.
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(name='EmailStatus',
fields=[('attachment', gradsite.gradnotes.models.Base64Field(blank=True, null=True)),])]
Run Code Online (Sandbox Code Playgroud)
我认为由于contrib_to_class中名称的更改,迁移自动检测程序变得混乱.我不确定什么可以解决.
class Base64Field(models.TextField):
def contribute_to_class(self, cls, name, private_only=False):
if not self.db_column:
self.db_column = name
self.field_name = name + '_base64'
super().contribute_to_class(cls,
name)
setattr(cls, self.field_name, property(self.get_data, self.set_data))
def get_data(self, obj):
return base64.b64encode(getattr(obj, self.name).encode('utf-8'))
def set_data(self, obj, data):
setattr(obj, self.field_name, base64.b64decode(data).decode('utf-8'))
Run Code Online (Sandbox Code Playgroud)
这似乎有效。和 之间存在混淆self.field_name,name导致contribute_to_class使用了错误的值(因此makemigrations第二次/使用时没有拾取该字段migrate)。
我对python3进行了特定的更改,即函数super的调用和使用base64。该set_data方法可能是错误的(我没有对此进行太多研究,因为您可能使用的是 python2 并且编码会有所不同),但迁移有效。
额外的好处:private_only您的方法中缺少参数contribute_to_class。
这是我得到的:
from test_app import models
e = models.EmailStatus()
e.attachment = "Hello world!"
e.attachment # Prints 'Hello world!'
e.attachment_base64 # Prints b'SGVsbG8gd29ybGQh'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
326 次 |
| 最近记录: |