如何在View Django中解决KeyError

时间:2019-09-03 23:43:32

标签: python django

当我尝试渲染视图时,收到一条错误消息“ / manifest处的KeyError”。我是第一次使用会话,因此不确定如何解决此问题。我正在尝试使用会话将字段“引用”从edit_manifest_frombrowse视图传递到manifest视图。有人可以向我解释是什么导致了此错误,为什么我可以修复它?代码和完整的回溯如下:

views.py

def edit_manifest_frombrowse(request, pk):
    item = get_object_or_404(Manifests, pk=pk)

    if request.method == "POST":
        form = CreateManifestForm(request.POST, instance=item)
        if form.is_valid():
            request.session["reference"] = form.cleaned_data["reference"]
        return redirect('manifest')


    else:
        form = CreateManifestForm(instance=item)

        return render(request, 'edit_manifest_frombrowse.html', {'form': form})


def manifest(request):
    form = CreateManifestForm(request.POST)

    if request.method == "POST":

        ...


    reference_id = request.session.pop('reference', None)
    data = Manifests.objects.all().filter(reference__reference=reference_id)
    form = CreateManifestForm(initial={

         'reference': Orders.objects.get(reference=reference_id),

         })
    total_cases = Manifests.objects.filter(reference__reference=reference_id).aggregate(Sum('cases'))

    context = {
    'reference_id': reference_id,
    'form': form,
    'data': data,
    'total_cases': total_cases['cases__sum'],

     }

    return render(request, 'manifest_readonly.html', context)

forms.py

class CreateManifestForm(forms.ModelForm):
    class Meta:
        model = Manifests
        fields = ('reference', 'cases', 'product_name', 'count', 'CNF', 'FOB')

models.py

#form which I am trying to submit
class Manifests(models.Model):

    reference = models.ForeignKey(Orders)

#just showing so you can see what the FK reference
class Orders(models.Model):

    reference = models.CharField(max_length=50, unique=True)

完整的回溯

Request Method: GET
Request URL: http://127.0.0.1:8000/manifest

Django Version: 1.11
Python Version: 2.7.10
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize',
 'bootstrap_modal_forms',
 'smart_selects',
 'unit']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/Library/Python/2.7/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/andrews/Desktop/WBU/web_unit/unit/views.py" in manifest
  325.     reference_id = request.session.pop('reference')

File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/base.py" in pop
  73.         return self._session.pop(key, *args)

Exception Type: KeyError at /manifest
Exception Value: 'reference'

1 个答案:

答案 0 :(得分:0)

您收到此错误,是因为这是pop方法的行为。

  

pop(key [,default]):如果key在字典中,请将其删除并返回其值,否则返回default。如果未提供默认值并且字典中没有key,则会引发KeyError。

因此,要解决此问题,您可以使用后备方法摆脱此错误。例如:

reference_id = request.session.pop("reference", None)

您的逻辑问题可能是导致您遇到此错误的根本原因。

if form.is_valid():
    request.session["reference"] = form.cleaned_data["reference"]
return redirect('manifest')

如果您的表单无效,则会话变量上将没有reference,因此您将无法在manifest视图中获取它。因此,尝试重定向到另一个视图或尝试执行以下操作:

if form.is_valid():
    # Do other stuff
    request.session["reference"] = form.cleaned_data["reference"]
else:
    # Do other stuff
    request.session["reference"] = ""
return redirect('manifest')

当您要使用查询集启动时,表单存在另一个问题。它将尝试将您的Orders查询集解析为表单的类似JSON的数据,这将提示错误。您应该尝试为reference字段创建替代字段,并在 init 方法上为该字段设置查询集,如下所示:

# forms.py
class CreateManifestForm(forms.ModelForm):
    reference = forms.ModelChoiceField(queryset=Orders.objects.none())

    class Meta:
        model = Manifests
        fields = ('reference', 'cases', 'product_name', 'count', 'CNF', 'FOB')

    def __init__(self, reference, *args, **kwargs):
        super(CreateManifestForm, self).__init__(*args, **kwargs)
        self.fields['reference'].queryset = reference

然后您可以像这样初始化表格:

form = CreateManifestForm(reference=Orders.objects.filter(reference=reference_id))

希望有帮助!