在自定义迁移中将模型作为apps.get_model('app_name','ModelName')`导入的逻辑是什么? [英] Whats the logic of importing models as `apps.get_model('app_name', 'ModelName')` in a custom migration

查看:194
本文介绍了在自定义迁移中将模型作为apps.get_model('app_name','ModelName')`导入的逻辑是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问这个问题是因为我遇到了这个 django.db.utils.IntegrityError:当我使用 django-hordak 时, lft列中的空值违反了非空约束 MPPT 模型。

I am asking this question because I ran into this django.db.utils.IntegrityError: null value in column "lft" violates not-null constraint when I was using django-hordak which uses MPPT models.

一些提议的解决方案是 hacky ,因为它们违反了常规做法,但它们工作。

Some of the solutions proposed are hacky as they go against common practice but they work.

基础

在Django中,编写自定义迁移时(例如,在创建基线时)数据。

In django when writing custom migrations for example when creating baseline data.

def forward_func(apps_registry, schema_editor):
    Model = apps_registry.get_model('app_name', 'ModelName')
    Model.objects.create(**{'field_1': 'field_1', 'field_2': 'field_2')
    # Do whatever you want with my Model 

在我的情况下,django-hordak具有帐户模型。如上所述, .objects.create(** data)
会在数据库上引发
IntegrityError。

In my situation django-hordak with the account model. That .objects.create(**data) raises theIntegrityError on the DB as specified above.

建议的解决方案

建议的解决方案之一是直接导入模型。

One of the solutions proposed solution is to import the model directly.

def forward_func(apps_registry, schema_editor):
    # Model = apps_registry.get_model('app_name', 'ModelName')
    # lets forget about importing the standard way because it will raise integrity error.

    from app_name.models import ModelName as Model
    # Now we can proceed to deal with our model without Integrity Error.
    Model.objects.create(**data)

这让我害怕可能的不良情况直接在迁移文件中导入模型的副作用。

This leaves me scared of possible undesirable side effects of importing models directly in migrations files.

因为一定有很好的理由说明未在迁移文件中以这种方式导入模型。

As there must be very good reasons why the model is not imported that way in the migration files.

我不是在寻找 MPTT 模型在导入标准方式时失败的原因,因为该问题具有在此处回答。 。
我想特别了解在迁移文件中使用 apps.get_model 导入模型的逻辑。

I am not looking for the reason why MPTT models fail when imported the standard way as that question has an answer here. . I want to understand particularly the logic behind importing models using apps.get_model in migration files.

推荐答案

这是一个很好的问题,因为实际上存在很大的差异。

that is a very good question, as there is in deed a very big difference.

如果导入模型,您将获取您的模型代码中当前定义的任何内容。但是,如果要删除模型会怎样?

If you import a model, you will get whatever is currently defined in your model code. But what happens if you want to remove a model? How do you make sure your migration will still work?

这就是为什么有 apps.get_model 的原因。它将根据先前迁移定义的状态为您提供虚拟模型。请注意,这与代码中的Model不同。除非它们是ORM API的一部分,否则它不具有您实现的任何自定义功能和行为。换句话说,大多数字段和元选项(例如订购和合作)。

That's why there is apps.get_model. It will give you a "virtual" Model based on state defined by the previous migrations. Note that this is not the same as the Model in your code. It does not have any of the custom functions and behaviors you implemented unless they are part of the ORM API. In other words mostly fields and meta options like ordering and co.

请注意,正确的签名是 apps 不是 app_registry 。请勿将其与 django.apps.apps 中的应用程序注册表相混淆。它也有一个 get_model 方法。但是,这将在您当前的代码中返回模型。

Please also note that the correct signature is apps not app_registry. It should not be confused with the app registry in django.apps.apps. It has a get_model method too. This one however will return the model in your current code.

我知道一开始(甚至以后)都会有些混乱。我建议遵循一个简单的规则。 请勿将自己的任何代码导入迁移。

I know it can be all a bit confusing at first (and even later). I would suggest following a simple rule. Do not import any of your own code into a migration. Backport behavior into the migration, if you must.

我希望这种区别对您有所帮助。如果您还有其他问题,请给我评论。我很高兴扩展我的答案。

I hope that distinction helps you a bit. Please leave me a comment if you have further questions. I am happy to extend my answer.

最佳
-乔

这篇关于在自定义迁移中将模型作为apps.get_model('app_name','ModelName')`导入的逻辑是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆