当我尝试迁移模型时,为啥会出现“无法序列化错误”?

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文件夹,然后尝试运行cmd python manage.py makemugrations 相同。我尝试了所有方法,但都犯了同样的错误。谢谢你的建议,我不知道,也许有一天会有所帮助。我评论了外键,它起作用了。意味着我的外键中有一些 django 不喜欢的东西。

以上是关于当我尝试迁移模型时,为啥会出现“无法序列化错误”?的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试使用 MVVM WPF 中的命令修改对象时,为啥在视图模型中出现空错误?

当我尝试显示模态视图时,为啥会出现 CoreAnimation 异常?

为啥当我尝试在 celery 任务中使用模型时,django 会引发“应用程序尚未加载”错误?

当我尝试通过更改 `extra.symfony.require` 来升级 Symfony 时,为啥会出现此错误?

当我尝试使用 Laravel 控制器方法处理 AJAX 请求时,为啥会出现此异常?

当我尝试使用文件维度作为行和列在 C 中创建矩阵时,为啥会出现错误?