首页 > 解决方案 > Foregin 键字段的值错误

问题描述

我正在尝试插入数据,但由于 ForeignKey 而在插入时出现 ValueError。

class Test(models.Model):
test_name = models.CharField(max_length=20, unique=True)
test_code = models.SlugField(max_length=10, name='Code',unique=True)
referance_value = models.CharField(name='Referance', max_length=20)

def __str__(self):
    return self.test_name    

class TestTaken(models.Model):
app_code = models.CharField(max_length=20,unique=True)
user_name = models.CharField(name='Username',max_length=20)
test_names = models.ForeignKey(Test, on_delete=models.CASCADE)
result_value = models.CharField(name='ResultValue',max_length=20)

def __str__(self):
    return self.app_code

下面是我的 View.py

    def alltestdata(request):
       if request.method == 'POST':
          app_code = request.POST.getlist('app_code')
          test_name = request.POST.getlist('name')
          test_list = request.POST.getlist('test_list')
          for i, j , k in zip(app_code, test_name, test_list):
              book = TestTaken(app_code=i, ResultValue=j, test_names=k, Username=request.user.username)
              book.save()
   return redirect('lab:Dashboard')

我收到以下错误

     ValueError: Cannot assign "'eeeee'": "TestTaken.test_names" must be a "Test" instance.

标签: djangodjango-models

解决方案


该错误包含您问题的答案:test_names是 a ForeignKey,而不是字符串。要从名称中设置它,您首先需要在Test表中找到键。这可以使用get或来完成get_or_create,具体取决于您希望如何处理缺失的测试。

注意:test_names对于该字段来说不是一个很好的名称,ForeignKey可能会导致这种混乱。它不应该是复数,并且指向一个Test对象,而不仅仅是一个名称。你可能想要更多类似的东西test

您的代码中存在一些额外的混淆。首先,您似乎在内部迭代中交换了值(j从获取其值test_name然后应用到ResultValue,虽然k来自test_list但去test_names代替)。您可以通过使用更明确的变量名称来避免这样的混淆。混淆的第二个来源是变量名app_codetest_nametest_list,所有这些似乎都是列表,但其中只有一个的名称似乎反映了这一点。

将这些点组合到代码中,尝试以下操作。请注意,我已经更改了一些变量的名称以反映我认为您的意图,并且我使用了简单的get_or_create,而您可能想要其他名称。调整以满足您的需求:

# in your model
class Test(models.Model):
    test_name = models.CharField(max_length=20, unique=True)
    test_code = models.SlugField(max_length=10, name='Code',unique=True)
    referance_value = models.CharField(name='Referance', max_length=20)

    def __str__(self):
        return self.test_name    

class TestTaken(models.Model):
    app_code = models.CharField(max_length=20,unique=True)
    user_name = models.CharField(name='Username',max_length=20)
    test = models.ForeignKey(Test, on_delete=models.CASCADE)
    result_value = models.CharField(name='ResultValue',max_length=20)

    def __str__(self):
        return self.app_code

# in View.py
def alltestdata(request):
   if request.method == 'POST':
      app_codes = request.POST.getlist('app_code')
      test_names = request.POST.getlist('name')
      scores = request.POST.getlist('test_list')
      for code, test_name, score in zip(app_codes, test_names, scores):
          test_obj, _ = Test.objects.get_or_create(test_name=test_name)
          book = TestTaken(app_code=code, ResultValue=score, test=test_obj, Username=request.user.username)
          book.save()
   return redirect('lab:Dashboard')

推荐阅读