首页 > 解决方案 > 将对象名称保存到子对象的 ForeignKey 字段中 - Django

问题描述

我有这些模型:

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')

使用如下方法将父对象保存到 db 中:

    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字段上的是 的 id MyModel1,因此,保存它就足够了,但是当我这样尝试时field1 = MyModel1.id

它说:

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

标签: djangopython-3.x

解决方案


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__方法是这些 ID 的组合,并且必须首先解析这个字符串;只有提取的值会匹配

而且我不明白你的__str__方法是如何工作的,因为这个模型没有field2,field3field4

我建议你重新考虑这种方法。看看泛型关系


推荐阅读