【问题标题】:how treat exception in django view?如何在 django 视图中处理异常?
【发布时间】:2017-03-25 02:37:05
【问题描述】:

我有一个带有 'Unique=True 属性的模型,该属性是指负责评估候选人的模型,评估者只能评估一个候选人。因此,当我尝试使用相同的评估者评估候选人时,Django 返回 ValueError,所以我尝试处理异常,但它不起作用...在 Django 中存在处理异常的特殊方法吗?

views.py(在 def 评估中):

from django.shortcuts import render, get_object_or_404
from .models import Candidate, Criterion, Evaluation
from django import forms
from .forms import CandForm
from .forms import EvalForm
from django.shortcuts import redirect


def canditate_list(request):
    candidates = Candidate.objects.all()

    eva = Evaluation.objects.all()
    eval_cand_list = []                                     #aqui guarda uma lista com os FK candidates convertidos p/ str

    context = {
        'candidates': candidates,
        'eva': eva
    }
    return render(request, 'app/candidate_list.html',context)

def candidate_detail(request, pk):
    candidate = get_object_or_404(Candidate, pk=pk)
    c_name = candidate.name                                 #pega o nome (string) do candidato
    c1 = Evaluation.objects.all()                           #guarda tds Evaluation na variavel  
    scores = []                                             #declara a array que vai receber as notas
    for c in c1:                                            
        cand = str(c.candidate)                             #guarda o nome do candidato do Evaluation atual
        if cand == c_name:                                  #confere se o Evaluation atual corresponde ao candidate atual(pk)
            scores += [c.score]

    _sum = 0                                                #variavel que guardara a soma declarada
    for s in scores:
        _sum += s                                           #faz a soma dos scores

    average = 0 
    if len(scores) > 0:
        average = _sum/len(scores)                              #tira a média

    context = {
        'candidate': candidate,
        'average': average
    }

    return render(request, 'app/candidate_detail.html', context)

def evaluation(request):
        if request.method == "POST":
            try:
                form2 = EvalForm(request.POST)
                if form2.is_valid():    
                    post = form2.save(commit=False)
                    post.save()
                    return redirect('canditate_list') 
            except ValueError:
                return('Você já avaliou este candidato!')
        else:
            try:
                form2 = EvalForm()
                return render(request, 'app/evaluation.html', {'criterions': form2,})
            except ValueError:
                return('Você já avaliou este candidato!')

def register(request):
    if request.method == "POST":
        form = CandForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            return redirect('candidate_detail', pk=post.pk)
    else:
        form = CandForm()
    return render(request, 'app/register.html', {'form': form})

models.py

from django.db import models
from jsonfield import JSONField
from site_.settings import MEDIA_ROOT
from django.core.validators import MaxValueValidator

class Criterion(models.Model):
    label = models.CharField(max_length=100)

    def  __str__(self):
        return self.label

class Candidate(models.Model):
    name = models.CharField(max_length=100)
    e_mail = models.EmailField(max_length=100, default = '')
    github = models.URLField(default = '')
    linkedin = models.URLField(max_length=100, default = '')
    cover_letter = models.TextField(default = '')
    higher_education = models.BooleanField(default = False)
    average = models.IntegerField(default = 0)
    #############################################################score = models.ForeignKey()
    docfile = models.FileField(upload_to='/home/douglas/Documentos/Django/my-second-blog/site_/media', null=True, blank=True)

    def  __str__(self):
        return self.name


class Evaluation(models.Model):
    candidate = models.ForeignKey(Candidate, unique=True)
    criterion = models.ForeignKey(Criterion, default='')
    score = models.PositiveIntegerField(default = 0, validators=[MaxValueValidator(10)])
    appraiser = models.ForeignKey('auth.User')

    def  __str__(self):
        return str(self.candidate)

[编辑]:

返回的错误是:

ValueError:视图 app.views.evaluation 未返回 HttpResponse 对象。它返回 None 。

【问题讨论】:

  • 具体错误是什么:`除了ValueError as e: print(e)`
  • 为什么 'print(e)' 我不能在这里使用 return()?我尝试这样做但没有结果
  • ValidationError的内容可能有助于调试,如果不打印,记录
  • 不要是 ValidationError 老兄,是 ValueError...

标签: python django django-views try-catch


【解决方案1】:

你得到的错误不是因为没有处理ValueError,而是因为没有向客户端返回 HTTP 响应。错误非常明确:

ValueError: The view app.views.evaluation didn't return an HttpResponse object. It returned None instead.

首先,当您尝试使用unique = True 约束将条目保存到数据库时引发的异常是IntegrityError

将您的 evaluation 视图更改为:

# views.py

from django.db import IntegrityError

def evaluation(request):
    # form2 initialization
    form2 = EvalForm()

    if request.method == "POST":
        form2 = EvalForm(request.POST)
        if form2.is_valid():    
            post = form2.save(commit=False)
            try:
                post.save()  # if candidate exists, then IntegrityError will be raised
            except IntegrityError:
                # Handle error here. Maybe add a message or something
                # and pass it though the context
    # if its a GET method, form2 will be unbound (ready to filled with data)
    # if its a POST method, form2 will be filled with any potential errors
    return render(request, 'app/evaluation.html', {'criterions': form2,})

【讨论】:

  • 谢谢你,你解决了我的问题......但我还有另一个问题,呵呵,首先:在 'except IntegrityError:' 之后我放了 return("message here") 但是当我尝试添加一个现有的候选人 def 不返回我的命令(我尝试使用'return HttpReponse()' to),他返回 django 模式消息错误:“与此候选人的评估已经存在。”,你知道我可以在哪里更改此消息并更改为个性化消息?第二:你怎么知道这是一个IntegrityError而不是一个ValueError,因为错误消息只引用了ValueError,你调试代码还是知道?
  • 每次出现约束暴力时,Django 都会抛出一个IntegrityErrorIntegrityErrorDatabaseError 的子类。我只知道。现在对于您问题的另一部分,在except 子句中,您应该添加return HttpResponse('Your message here') 或更好的return render(request, 'app/evaluation.html', {'criterions': form2, message: 'Your message here'}),并在evaluation.html 访问消息中添加{{ message }}
  • 我明白了!谢谢老哥的关注!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-16
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
相关资源
最近更新 更多