KeyError:如何在form_invalid()中正确设置变量

时间:2018-06-22 05:40:13

标签: django django-forms

作为介绍,我知道我在 views.py 中的行中做错了事,但我不知道如何正确设置该变量在search_text = form.cleaned_data['search_text']

问题

如果用户在数据库中已经存在的form_invalid()中输入了search_text,则会引起错误:“带有此搜索文本的标签已经存在。”

解决方案

如果用户输入数据库中已经存在的Form,请检查输入的search_text是否与数据库中现有的search_text相匹配。如果是这样,请渲染 results.html

错误

search_text

CODE

models.py

Request Method: POST
Request URL:    http://ozxlitwi.apps.lair.io/search_query/
Django Version: 2.0
Exception Type: KeyError
Exception Value: 'search_text'
Exception Location: /mnt/project/mapping_twitter/views.py in form_invalid, line 31
Python Executable:  /mnt/data/.python-3.6/bin/python
Python Version: 3.6.5
Python Path:    
['/mnt/project',
 '/mnt/data/.python-3.6/lib/python36.zip',
 '/mnt/data/.python-3.6/lib/python3.6',
 '/mnt/data/.python-3.6/lib/python3.6/lib-dynload',
 '/usr/local/lib/python3.6',
 '/mnt/data/.python-3.6/lib/python3.6/site-packages']

forms.py

import re

from django.db import models
from twython import Twython


class Location(models.Model):
    """ Model representing a Location (which is attached to Hashtag objects
    through a M2M relationship) """

    name = models.CharField(max_length=1400)

    def __str__(self):
        return self.name


class Hashtag(models.Model):
    """ Model representing a specific Hashtag serch by user """

    search_text = models.CharField(max_length=140, primary_key=True)
    locations = models.ManyToManyField(Location, blank=True)

    def __str__(self):
        """ String for representing the Model object (search_text) """
        return self.search_text

    def display_locations(self):
        """ Creates a list of the locations attached to the Hashtag model """
        return list(self.locations.values_list('name', flat=True).all())

views.py

from django import forms
from django.forms import ModelForm
from django.utils.translation import ugettext_lazy as _

from .models import Location, Hashtag


class SearchHashtagForm(ModelForm):
    """ ModelForm for user to search by hashtag """

    def clean_hashtag(self):
        data = self.cleaned_data['search_text']
        # Check search_query doesn't include '#'. If so, remove it.
        if data[0] == '#':
            data = data[1:]
        # return the cleaned data
        return data

    class Meta:
        model = Hashtag
        fields = ['search_text',]
        labels = {'search_text':_('Hashtag Search'), }
        help_texts = { 'search_text': _('Enter a hashtag to search.'), }

1 个答案:

答案 0 :(得分:1)

更改为:

def form_invalid(self, form):
    search_text = form.cleaned_data['search_text']
    if Hashtag.objects.filter(pk=search_text).exists():
        return HttpResponseRedirect(reverse('mapping_twitter:results'))
    else:
        return self.form_invalid(form)

def form_invalid(self, form):
    search_text = self.request.POST.get('search_text')
    if search_text and Hashtag.objects.filter(pk=search_text).exists():
        return HttpResponseRedirect(reverse('mapping_twitter:results'))
    else:
        return super(HashtagSearch, self).form_invalid(form)

form.cleaned_data是在表单生效后创建的。因此,当表单无效时,form.cleaned_data为无。