#django #python-3.x
#django #python-3.x
Вопрос:
У меня есть эти модели:
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
поле родительского объекта?
Редактировать
В этом myfk
поле сохраняется идентификатор MyModel1
, поэтому было бы достаточно сохранить это, но когда я пытаюсь вот так field1 = MyModel1.id
В нем говорится:
ValueError at /admin/mymodel/instance/add/
Cannot assign "98": "MyModel2.field1.id" must be a "MyModel1" instance.
Комментарии:
1. Я думаю, что это должно быть
__str__()
2. Вы всегда «сохраняете фактический родительский экземпляр в поле ForeignKey дочернего объекта», по крайней мере, в коде Django. На уровне базы данных сохраняется первичный ключ родительского объекта. Строковое представление родительского объекта не имеет к этому никакого отношения.
Ответ №1:
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
.
Я предлагаю вам пересмотреть подход. Взгляните на общие отношения.
Комментарии:
1. Привет, хорошее объяснение, большое вам спасибо, но извините, там написано недопустимый литерал для int () с основанием 10, когда я сохраняю родительский объект с помощью метода str , он содержит комбинацию чисел и строк, (field1, field2, field3) может ли это быть проблемой?
2. Привет, Иван, большое тебе спасибо, я выполнил несколько запросов к базе данных, что необходимо сохранить, так это фактический ‘id’ в поле ‘myfk’, оно должно его отобразить, я отредактировал свой вопрос, если хочешь, спасибо.
3. Ваш запутанный (?) код и сообщения об ошибках не совпадают.
4. Я имею в виду, если я добавлю идентификатор ‘instance’, который будет идентификатором MyModel1, он должен быть сохранен как таковой, я не понимаю, почему эта ошибка, кажется, что я должен явно объявить экземпляр MyModel1