Django ContenTypes не сохраняет "content_object" при миграции - PullRequest
0 голосов
/ 16 марта 2020

Начиная с существующей ModelA.

Требования:

  • в зависимости от ModelA.type, ModelA.example будет отношением к ModelB или Model C.
  • предсуществующие Экземпляры ModelA необходимо инициализировать по умолчанию, в зависимости от ModelA.type (ModelA.type уже не обнуляется)

Текущее решение:

  1. Я создал отношение generi c для ModelA:

    class ModelA:
        ...
        example_content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, null=True)
        example_id = models.PositiveIntegerField(null=True)
        example = GenericForeignKey("example_content_type", "example_id")
    
  2. Я запустил ./manage.py makemigrations, который создал миграцию с пустыми полями

  3. Я изменил поля example_content_type и example_id на ненулевые

  4. снова запустил makemigrations и создал следующий пользовательский прогон Python перед автоматически сгенерированными изменениями:

    def set_default_example(apps, schema_editor):
        ModelA = apps.get_model("myExample", "ModelA")
        all_model_a = ModelA.objects.all()
        for model_a in all_model_a:
            example = None
            if model_a.type == "type_a":
                example = ExampleForTypeA.objects.create(foo="foo")
    
            if model_a.type == "type_b":
                example = ExampleForTypeB.objects.create(bar="bar")
    
            model_a.example = example
            model_a.save()
    

    попытка перенастроить это бросает с django.db.utils.IntegrityError: column "example_content_type_id" contains null values

  5. Я вручную создал и присвоил content_type (работает, только если я назначил поле _id). он по-прежнему выдает: django.db.utils.IntegrityError: column "example_id" contains null values, поэтому я вручную создал и присвоил example_id, получив следующий код:

    def set_default_example(apps, schema_editor):
        ModelA = apps.get_model("myExample", "ModelA")
        all_model_a = ModelA.objects.all()
        for model_a in all_model_a:
            example = None
            content_type = None
            if model_a.type == "type_a":
                example = ExampleForTypeA.objects.create(foo="foo")
                content_type = ContentType.objects.get_for_model(ExampleForTypeA)
    
            if model_a.type == "type_b":
                example = ExampleForTypeB.objects.create(bar="bar")
                content_type = ContentType.objects.get_for_model(ExampleForTypeB)
    
            model_a.example_content_type_id = content_type.id
            model_a.example_id = example.id
            model_a.example = example
            model_a.save()
    

Вопрос:

  • Этот код работает, но мне кажется странным, что мне приходится вручную присваивать example_content_type_id и example_id, это тот крайний случай, когда .save () не обрабатывает Generi c Relations?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...