Сохранить имя объекта в поле ForeignKey дочернего объекта - Django - PullRequest
0 голосов
/ 26 марта 2019

У меня есть следующие модели:

class MyModel1(models.Model):
    field1 = models.CharField(max_length=128, blank=True, null=True)
    fieldrelated1 = models.OneToOneField('MyModel2', max_length=128, blank=True, null=True, related_name='mymodel2')
    fieldrelated2 = models.OneToOneField('MyModel3', max_length=128, blank=True, null=True, related_name='mymodel3')
    fieldrelated3 = models.OneToOneField('MyModel4', max_length=128, blank=True, null=True, related_name='mymodel4')

class MyModel2(models.Model):
    field2 = models.CharField(max_length=128, blank=True, null=True)
    myfk = models.ForeignKey(MyModel1, max_length=128, blank=True, null=True)

class MyModel3(models.Model):
    field3 = models.CharField(max_length=128, blank=True, null=True)
    test = models.CharField(max_length=128, blank=True, null=True)

class MyModel4(models.Model):
    field4 = models.CharField(max_length=128, blank=True, null=True)
    test = models.CharField(max_length=128, blank=True, null=True)

Затем этот метод:

def create_child_objects(instance, created, rad, **kwargs):
    if not created or rad:
        return
        field1 = instance.field1

    if not instance.fieldrelated1_id:
        fieldrelated1, _ = MyModel2.objects.get_or_create(field1=field2)
    instance.fieldrelated1 = fieldrelated1

    if not instance.fieldrelated2_id:
        fieldrelated2, _ = MyModel3.objects.get_or_create(field1=field3)
    instance.fieldrelated2 = fieldrelated2

    if not instance.fieldrelated3_id:
        fieldrelated3, _ = MyModel4.objects.get_or_create(field1=field4)
    instance.fieldrelated3 = fieldrelated3

    instance.save()

models.signals.post_save.connect(create_child_records, sender=MyModel1, dispatch_uid='create_child_objects')

Пока что этот метод работает для сохранения родительского элемента и сохранения определенных полей при создании дочернего элемента.

Моя проблема возникает, когда я хочу, например, вместо сохранения CharField родительского элемента в дочернем элементе CharField, я хочу сохранить фактический родительский экземпляр в поле ForeignKey дочернего элемента, например так:

def create_child_objects(instance, created, rad, **kwargs):
    if not created or rad:
        return
    field1 = instance.__str__

    if not instance.fieldrelated1_id:
        fieldrelated1, _ = MyModel2.objects.get_or_create(field1=myfk)
    instance.fieldrelated1 = fieldrelated1

    if not instance.fieldrelated2_id:
        fieldrelated2, _ = MyModel3.objects.get_or_create(field1=field3)
    instance.fieldrelated2 = fieldrelated2

    if not instance.fieldrelated3_id:
        fieldrelated3, _ = MyModel4.objects.get_or_create(field1=field4)
    instance.fieldrelated3 = fieldrelated3

    instance.save()

models.signals.post_save.connect(create_child_objects, sender=MyModel1, dispatch_uid='create_child_records')

Родительский объект сохраняется в БД с помощью метода, подобного следующему:

    def __str__(self):
        return ('{}: {}: {}'.format(self.field1, self.field2, self.field3))

Итак, после второго create_child_objects он выдает мне следующее:

TypeError at /admin/mymodel/instance/add/
int() argument must be a string, a bytes-like object or a number, not 'method'

Итак, как я могу сохранить дескриптор родительского объекта в поле ForeignKey для родительского объекта?

EDIT

Что сохраняется на этом myfk поле является идентификатором MyModel1, поэтому было бы достаточно сохранить это, но когда я пытаюсь сделать это следующим образом field1 = MyModel1.id

Там написано:

ValueError at /admin/mymodel/instance/add/
Cannot assign "98": "MyModel2.field1.id" must be a "MyModel1" instance.

1 Ответ

1 голос
/ 26 марта 2019
field1 = instance.__str__

изменить на

field1 = instance.__str__()

или

field1 = str(instance)

__str__ - это метод, поэтому ваше назначение field1 указывает на этот метод, а не на результат метода.

UPD

Все строки MyModel[2-4].objects.get_or_create(field1=field2) неверны:

  • эти модели не имеют поля field1, поэтому правильный фильтр будет field[2-4]=field1
  • в любом случае, я предполагаю, что он никогда ничего не будет совпадать, потому что метод __str__ является комбинацией этих идентификаторов, и эта строка должна быть проанализирована первой;только извлеченные значения будут соответствовать

И я не понимаю, как работает ваш метод __str__, так как эта модель не имеет field2, field3 и field4.

Я предлагаю вам переосмыслить подход.Взгляните на родовые отношения .

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