Django вставляет данные в модель с внешним ключом - PullRequest
0 голосов
/ 24 августа 2018

Я использую модели Django и сталкиваюсь с проблемами. У меня есть пара моделей, в которые я пытаюсь загрузить данные, одна с внешним ключом к другой. В качестве примера я буду использовать две модели, но надеюсь, что смогу написать код, который будет обобщать для работы с моделями с разными именами и разными именами полей. Модели выглядят следующим образом:

class ProgramInfo(models.Model):
    program_code = models.CharField(max_length=5, primary_key=True)
    ...

class StudentInfo(models.Model):
    ...
    program_code = models.ForeignKey('ProgramInfo', on_delete=models.PROTECT)

У меня также есть словарь _model_dict с именами полей StudentInfo в качестве ключей, а значения являются значениями, которые я хочу поместить в модель. Когда я бегу

_model.objects.update_or_create(**_model_dict)

Это говорит мне

Cannot assign "'ABCD'": "StudentInfo.program_code" must be a "ProgramInfo" instance.

Даже если это значение существует в таблице ProgramInfo.
У меня нет проблем с вставкой данных в модели без внешних ключей, используя тот же метод.

Насколько я понимаю, значение ключа в _model_dict поля внешнего ключа должно быть не просто значением для отдельного поля, а объектом модели, на который ссылается внешний ключ.
Я попытался выделить поля внешнего ключа, чтобы иметь возможность использовать model_get с фильтром, получить строку из целевой модели и поместить ее в _model_dict, но я не смог выяснить, как получить целевую модель, учитывая известное поле ForeignKey , Поскольку я намерен обобщать, я не хочу указывать целевую модель в конкретном коде, но хотел бы получить ее из поля, которое мне удалось заключить, было полем внешнего ключа. Я уже много часов гуглю и не могу найти атрибут для целевой модели a поля ForeignKey.

Я не знаю, будет ли это полезно, но вот код, который я использовал для создания класса для внешнего ключа:

                # check for foreign keys
            _model_field_objects = [f for f in _model._meta.get_fields()]
            foreign_key_fields_dict = {}
            for field in _model_field_objects:
                if field.__class__ is ForeignKey:
                    foreign_key_fields_dict[field.name] =  field #here i try to obtain target model of the field
            print("Foreign key fields are: " + str(foreign_key_fields_dict))
            sys.stdout.flush()

            for row in data:
                _model_dict = {key: value for key, value in zip(titles, row) if key in _model_field_names}

                # adjust foreign key to their class
                for key in _model_dict:
                    filter_arguments = {}
                    if key in foreign_key_fields_dict:
                        filter_arguments[key] = _model_dict[key]
                        _model_dict[key] = foreign_key_fields_dict[key].objects.filter(**filter_arguments)

                # insert to table
                _model.objects.update_or_create(**_model_dict)

Я, наверное, слишком усложняю это. Если есть простой способ, которым Django предусматривает добавление в модель с внешними ключами, учитывая известное значение для поля внешнего ключа (а не полный объект для модели, на которую он указывает), я был бы рад узнать об этом.
Заранее благодарим за любую доступную помощь!

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

Я решил это не элегантным способом, который работает для меня.Другие ответы могут быть лучше, но я слишком напуган, чтобы изменить свой код на данный момент, поскольку он, кажется, работает.Вот что я сделал в случае, если это может помочь кому-либо еще: Использование:
from pprint import pprint pprint(vars(myobject)) Мне удалось обнаружить, что объект типа ForeignKey имеет атрибут ForeignKey.related_model.После того, как у меня была модель, я мог использовать ее следующим образом, чтобы получить строку в модели, на которую указывают:

field.related_model.objects.get(pk=_model_dict[key])

, где field - это поле в модели, в которое я пытаюсь вставить данныев.Результат этого может быть помещен в словарь _model_dict, содержащий все другие значения полей для модели, в которую я вставляю данные, поэтому для вставки данных использовалось следующее:

_model.objects.update_or_create(**_model_dict)

ПРИМЕЧАНИЕ: update_or_createиногда происходил сбой, когда говорилось, что есть проблема с уникальностью, которая, как я думал, была частью "update_or", которую нужно было решить.В любом случае, добавив попытку / кроме как вокруг, это решило эту проблему для меня - хотя я знаю, что это хак ..

0 голосов
/ 25 августа 2018

, поскольку program_code является первичным ключом в модели ProgramInfo, вы можете установить или получить значение этого поля: например,

, например, у вас есть экземпляр ProgramInfo с ключом primarykeyчто его значение равно «abcd», вы можете создать StudentInfo, используя это так:

StudentInfo.objects.create(program_code_id='abcd', ..... other fields ....)

, потому что program_code_id - это то, что действительно хранится в базе данных StudentInfo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...