当我使用过滤器检查相同的参数时,get_or_create 返回错误,即存在多个对象值,它返回 0 个对象

Mis*_*tyD 0 django orm django-models django-orm

我正在尝试使用get_or_create方法来查看记录是否存在。如果记录存在,则什么都不做,否则创建它。

这个模型基本上用在失败的命令上

 class modelStudentExamsPerformed(models.Model):
        patient = models.ForeignKey(modelPatient)
        student = models.ForeignKey(modelStudent,on_delete=models.CASCADE)
        normalBodyPart = models.ForeignKey(modelNormalBodyPartResult,default=None,blank=True,null=True)
        abnormalBodyPart = models.ForeignKey(modelAbnormalBodyPartResult,default=None,blank=True,null=True)
        tool = models.CharField(max_length=128, default="")
Run Code Online (Sandbox Code Playgroud)

现在这是使用上述模型但失败的命令

exams.modelStudentExamsPerformed.objects.get_or_create()(patient=patient_qset, student=stud_qset,abnormalBodyPart=qset[0],normalBodyPart=None,date=None)
Run Code Online (Sandbox Code Playgroud)

上面的语句给了我错误:

get() returned more than one modelStudentExamsPerformed -- it returned 2!
Run Code Online (Sandbox Code Playgroud)

现在这是我遇到麻烦的地方。当我通过我的管理员查看数据库时,我确实注意到两个对象,但这些对象都有一个关联的值normalBodyPart并且它们abnormalBodyPart是空的。既然我明确指定并分配了一个值,abnormalBodyPart为什么 django 说两个项目已经存在?我希望这是有道理的 。

让我们以另一种方式解释这一点,假设有两个语句 1 和 2。语句 1 根据指定的参数获取或创建记录。这个 get 或 create 失败,因为 django 认为已经有两条记录。但是语句 2 使用相同的确切参数并返回 0 条记录。这是为什么 ?我在这里缺少什么和不理解?

声明 1:

exams.modelStudentExamsPerformed.objects.get_or_create()(patient=patient_qset, student=stud_qset,abnormalBodyPart=qset[0],normalBodyPart=None,date=None)
Run Code Online (Sandbox Code Playgroud)

当显然该表中的所有对象都没有 的值时abnormalBodyPart。我通过执行以下操作验证了这一点

声明 2:

k = exams.modelStudentExamsPerformed.objects.filter(patient=patient_qset, student=stud_qset,abnormalBodyPart=qset[0], normalBodyPart=None,date=None)
Run Code Online (Sandbox Code Playgroud)

上面的语句 2 不返回任何内容。我的问题是为什么语句 2 不返回任何内容,而语句 1 抱怨已经有 2 个项目,因此get调用失败。

Mel*_*vyn 6

您在get_or_create()不带参数的情况下调用,然后__call__()在结果实例上调用该 方法。

将关键字放在里面get_or_create以使其正常工作。还要再次研究方法签名:您缺少一个defaults参数。该方法的工作原理如下:

  • 过滤提供的关键字参数,“默认值”除外
  • 如果没有返回任何内容,请使用这些关键字参数创建一个新实例并使用“defaults”关键字参数,它应该是一个用于填充其他字段的字典。

有时,最好说明一下:

instance, created = Players.objects.get_or_create(
    username='Lagolas',
    defaults={'class': 'ranger', 'gender': 'male'}
)
Run Code Online (Sandbox Code Playgroud)

相当于:

try:
    instance = Players.objects.get(username='Lagolas')
    return instance, False
except Players.DoesNotExist:
    instance = Players.objects.create(
        username='Lagolas', class='ranger', gender='male'
    )
    return instance, True
Run Code Online (Sandbox Code Playgroud)