当我尝试迁移模型时,为啥会出现“无法序列化错误”?
Posted
技术标签:
【中文标题】当我尝试迁移模型时,为啥会出现“无法序列化错误”?【英文标题】:Why do I get the "cannot serialize error" when I try to migrate my model?当我尝试迁移模型时,为什么会出现“无法序列化错误”? 【发布时间】:2020-07-31 01:42:02 【问题描述】:嗯,我对 django 很陌生,所以我很容易迷路。我正在尝试构建我的模型,使用我的 sql 模型作为参考(我想人们就是这样做的)。 我解决了大多数错误,但最后一个错误让我很生气,而且我在网上找不到帮助。 这是我的代码:
from phone_field import PhoneField
# Create your models here.
class Room(models.Model):
number = models.IntegerField(primary_key=True, unique=True)
duration = models.IntegerField(default="3")
max_score = models.IntegerField(default="100")
name = models.CharField(max_length=30)
status = models.CharField(max_length=15, default="inactive")
class Credit(models.Model):
value = models.CharField(max_length=3)
class Language(models.Model):
name = models.CharField(max_length=20, default="chinese")
class Token(models.Model):
token_id = models.IntegerField(primary_key=True, unique=True)
class Level(models.Model):
value = models.IntegerField(default="1")
class Event(models.Model):
name = models.CharField(max_length=80)
phone_number = PhoneField(blank=True, help_text='Contact phone number')
date = models.DateTimeField('date of event')
members = models.IntegerField()
credit = models.ForeignKey(Credit, on_delete=models.DO_NOTHING)
language = models.ForeignKey(Language, on_delete=models.SET_DEFAULT, default="chinese")
level = models.ForeignKey(Level, on_delete=models.SET_DEFAULT, default="1")
class Team(models.Model):
name = models.CharField(max_length=80)
token_id = models.ForeignKey(Token, blank=True, null=True,on_delete=models.SET_NULL)
event_id = models.ForeignKey(Event, on_delete=models.CASCADE)
language = models.ForeignKey(Language, on_delete=models.SET_DEFAULT, default=Event.language)
level = models.ForeignKey(Level, on_delete=models.SET_DEFAULT, default=Event.level)
players_number = models.IntegerField(default="3")
end_time = models.DateTimeField()
activation_status = models.BooleanField(default=True)
active_room = models.ForeignKey(Room, blank=True, null=True,on_delete=models.SET_NULL)
total_score = models.IntegerField(default="0")
class ScoreTable(models.Model):
team_id = models.ForeignKey(Team,blank=True, null=True, on_delete=models.CASCADE)
room_number = models.ForeignKey(Room, blank=True, null=True,on_delete=models.CASCADE)
score = models.IntegerField(default="0")
time = models.DateTimeField('time of scoring', auto_now_add=True)
class BestScore(models.Model):
team_name = models.CharField(max_length=80)
total_score = models.IntegerField(default="0")
date = models.DateTimeField()
当我尝试迁移我的模型时,我收到了这个错误:
(mysite) MBPdeAlexandre:mysite nivren$ python manage.py makemigrations manager
Migrations for 'manager':
manager/migrations/0001_initial.py
- Create model BestScore
- Create model Credit
- Create model Event
- Create model Language
- Create model Level
- Create model Room
- Create model Token
- Create model Team
- Create model ScoreTable
- Add field language to event
- Add field level to event
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/core/management/base.py", line 328, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/core/management/base.py", line 369, in execute
output = self.handle(*args, **options)
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/core/management/commands/makemigrations.py", line 182, in handle
self.write_migration_files(changes)
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/core/management/commands/makemigrations.py", line 219, in write_migration_files
migration_string = writer.as_string()
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/db/migrations/writer.py", line 141, in as_string
operation_string, operation_imports = OperationWriter(operation).serialize()
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/db/migrations/writer.py", line 99, in serialize
_write(arg_name, arg_value)
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/db/migrations/writer.py", line 51, in _write
arg_string, arg_imports = MigrationWriter.serialize(item)
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/db/migrations/writer.py", line 271, in serialize
return serializer_factory(value).serialize()
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/db/migrations/serializer.py", line 37, in serialize
item_string, item_imports = serializer_factory(item).serialize()
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/db/migrations/serializer.py", line 199, in serialize
return self.serialize_deconstructed(path, args, kwargs)
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/db/migrations/serializer.py", line 86, in serialize_deconstructed
arg_string, arg_imports = serializer_factory(arg).serialize()
File "/Users/nivren/.virtualenvs/mysite/lib/python3.8/site-packages/django/db/migrations/serializer.py", line 336, in serializer_factory
raise ValueError(
ValueError: Cannot serialize: <django.db.models.fields.related_descriptors.ForwardManyToOneDescriptor object at 0x10a7d5310>
There are some values Django cannot serialize into migration files.
For more, see https://docs.djangoproject.com/en/3.0/topics/migrations/#migration-serializing
好的,我的外键“语言”在“团队”和“事件”中被引用,“事件”也在“团队”中被引用。这在我的脑海中看起来很清楚:一个活动可以设置一种语言,但是参加这个活动的一个团队可能会超载语言选择,总是从语言列表中选择。在 django 模型哲学中有什么我不理解的东西吗? 感谢您的帮助,同时我会继续寻找答案:)
【问题讨论】:
您为什么要尝试将正则表达式验证器序列化到您的模型中?验证器就是这样,它应该验证您的数据,但它不应该是您模型的一部分。在您的开始跟踪底部有一个链接,其中讨论了序列化以及您可以序列化和不能序列化的内容。 我更改了用于存储的功能。你是对的。但之后还是犯了同样的错误。它不喜欢我的外键,但我不明白为什么。 【参考方案1】:好的,我发现了我的问题。我是说如果“团队”的语言被删除,那么它应该使用“事件”中的语言值。 Django 不喜欢它。我不知道为什么,但它会导致问题。现在我输入了一个真正的默认值,它接受了我的迁移。如果有人可以在评论中向我解释,那就太好了:)
【讨论】:
【参考方案2】:我认为问题在于您的模型,特别是 PhoneModel
。
您使用错误来实现验证器。
参考此链接了解验证器:https://docs.djangoproject.com/en/3.0/ref/validators/#writing-validators
你的代码应该是这样的
phone_regex = RegexValidator(regex=r'^\+?1?\d9,15$', message="Phone number must be: '+999999999'. Max 15 digits.")
class PhoneModel(models.Model):
phone_number = models.CharField(validators=[phone_regex], max_length=17, blank=True) # validators should be a list
你也可以这样实现它:
class ReceiverForm(forms.ModelForm):
phone_number = forms.RegexField(regex=r'^\+?1?\d9,15$',
error_message = ("Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."))
纠正我,它不起作用
【讨论】:
这里也一样,我用我下载的另一个包更改了手机部分。但它似乎不喜欢我的外键。我更新了帖子。 请先删除migration文件夹,然后尝试运行cmdpython manage.py makemugrations
相同。我尝试了所有方法,但都犯了同样的错误。谢谢你的建议,我不知道,也许有一天会有所帮助。我评论了外键,它起作用了。意味着我的外键中有一些 django 不喜欢的东西。以上是关于当我尝试迁移模型时,为啥会出现“无法序列化错误”?的主要内容,如果未能解决你的问题,请参考以下文章
当我尝试使用 MVVM WPF 中的命令修改对象时,为啥在视图模型中出现空错误?
当我尝试显示模态视图时,为啥会出现 CoreAnimation 异常?
为啥当我尝试在 celery 任务中使用模型时,django 会引发“应用程序尚未加载”错误?
当我尝试通过更改 `extra.symfony.require` 来升级 Symfony 时,为啥会出现此错误?