【问题标题】:django local variable 't' referenced before assignment赋值前引用的 django 局部变量 't'
【发布时间】:2020-08-22 06:07:50
【问题描述】:

我看到这是一个常见错误,我确实查看了其他帖子,但他们没有帮助我。

我收到了错误

Exception Value: local variable 't' referenced before assignment

但是在我的 if 验证中,我的 t 变量在声明它不是的地方声明了 3 行。范围应该适合我的回报。

有问题的功能:

def create(response):
        #response.user
        if response.method == "POST":
                form = CreateNewTrade(response.POST)
                if form.is_valid():
                        n = form.cleaned_data["name"]
                        t = AssetList(name=n)
                        t.save()
                        response.user.assetlist.add(t)

                return HttpResponseRedirect("/userdash/%i" %t.id) #we fail at this t variable

完整代码:

$ cat userdash/views.py

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from .models import AssetList, Items
from .forms import CreateNewTrade

# Create your views here.


#def index(response):
#       return HttpResponse("<h1>Hello Dark World!</h1>")

def userdash(response, id):
        ls = AssetList.objects.get(id=id)
        if response.method == "POST":
                print(response.POST)
                if response.POST.get("save"):
                        for item in ls.items_set.all():
                                if response.POST.get("c" + str(item.id)) == "clicked":
                                        item.sell_asset = True
                                else:
                                        item.sell_asset = False

                                item.save()

                elif response.POST.get("newItem"):
                        txt = response.POST.get("new")
                        if len(txt) > 2: #this validation is retarded and needs to be fixed
                                ls.items_set.create(user_asset=txt, sell_asset=False)
                        else:
                                print("invalid")


        #items = ls.items_set.get(id=1)
        #return HttpResponse("<h1>User Dashboard!</h1><h2>%s</h2><br></br><p>%s</p>" %(ls.name, str(items.user_asset)))
        return render(response, "userdash/list.html", {"ls":ls})

def home(response):
        #pass
        return render(response, "userdash/home.html", {})

def create(response):
        #response.user
        if response.method == "POST":
                form = CreateNewTrade(response.POST)
                if form.is_valid():
                        n = form.cleaned_data["name"]
                        t = AssetList(name=n)
                        t.save()
                        response.user.assetlist.add(t)

                return HttpResponseRedirect("/userdash/%i" %t.id)
        else:
                form = CreateNewTrade()
        return render(response, "userdash/create.html", {"form":form})

def view(response):
        return render(response, "userdash/view.html", {})

$ cat userdash/models.py

from django.db import models
from django.contrib.auth.models import User
# Create your models here.

class AssetList(models.Model):
        user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="assetlist", null=True)
        name = models.CharField(max_length=200)

        def __str__(self):
                return self.name

class Items(models.Model):
        assetlist = models.ForeignKey(AssetList, on_delete=models.CASCADE)
        user_asset = models.CharField(max_length=300)
        sell_asset = models.BooleanField()

        def __str__(self):
                return self.user_asset

$ cat userdash/templates/userdash/view.html

{% extends 'userdash/base.html' %}

{% block title %} View page {% endblock %}
{% load crispy_forms_tags %}


{% block content %}
        {% for td in user.assetlist.all %}
                        <p><a href="/{{td.id}}">{{td.name}}</a></p>
        {% endfor %}

{% endblock %}

错误:

UnboundLocalError at /create/

local variable 't' referenced before assignment

Request Method:     POST
Request URL:    http://192.168.42.14:8081/create/
Django Version:     3.0.5
Exception Type:     UnboundLocalError
Exception Value:    

local variable 't' referenced before assignment

Exception Location:     ./userdash/views.py in create, line 51
Python Executable:  /usr/local/bin/uwsgi
Python Version:     3.7.3
Python Path:    

['.',
 '',
 '/home/piggy/Env/lib/python37.zip',
 '/home/piggy/Env/lib/python3.7',
 '/home/piggy/Env/lib/python3.7/lib-dynload',
 '/usr/lib/python3.7',
 '/home/piggy/Env/lib/python3.7/site-packages']

如何分配我的 t 变量以便我的 return 语句接受它?

【问题讨论】:

    标签: python django django-views django-templates


    【解决方案1】:

    这是因为您的表单无效。因此,它会直接返回HttpResponseRedirect 部分,其中t 没有定义。

    def create(response):
            if response.method == "POST":
                    form = CreateNewTrade(response.POST)
    
                    # Because form.is_valid() failed, t will be undefined
                    if form.is_valid():
                            n = form.cleaned_data["name"]
    
                            # Here only, you have assigned value of t
                            t = AssetList(name=n)
                            t.save()
                            response.user.assetlist.add(t)
    
                    # Returns directly to this line, if you see indentation, t is not defined 
                    return HttpResponseRedirect("/userdash/%i" %t.id)
    

    请参阅上面的 cmets 以了解发生了什么。因此,可能的错误减少器可能是:

    # Define t globaly inside create() method
    def create(response):
            t = None
            if response.method == "POST":
    

    现在,您已经在函数内部全局定义了t=None,它不会显示之前显示的错误。但是,仍然会有问题,因为tNone。所以,它不会有任何属性id。因此,将显示has no attribute DoesNotExist。因此,您必须考虑如果表单无效该怎么办,重定向到哪里。

    或者,如果表单无效,您可以使用 else 语句来处理问题。喜欢:

    def create(response):
            if response.method == "POST":
                    form = CreateNewTrade(response.POST)
    
                    # Because form.is_valid() failed, t will be undefined
                    if form.is_valid():
                            n = form.cleaned_data["name"]
    
                            # Here only, you have assigned value of t
                            t = AssetList(name=n)
                            t.save()
                            response.user.assetlist.add(t)
    
                            return HttpResponseRedirect("/userdash/%i" %t.id)
    
            # When if statements doesnot apply, always come to this line unless it goes inside form.is_valid()
            return HttpResponseRedirect("/userdash/")   # redirect to the page whose arguments doesnot depend upon the form subbmission
    

    现在,我希望你明白问题所在。

    【讨论】:

      【解决方案2】:

      你的create函数应该返回什么表单无效?

      如果表单无效,您将引用不存在的 t 变量的值。您应该在 if 之外创建此变量(如果您想返回默认值),或者如果表单无效,则向用户返回错误。

      【讨论】:

        【解决方案3】:

        在这里,您在 if 语句中定义了 t,但它不能保证始终运行,因此有可能没有 t 变量(如果 if 语句失败)。 t 也是 if 语句的局部变量,不能在它之外使用(除非它在 ​​if 语句下)。

        `def create(response):
                #response.user
                if response.method == "POST":
                        form = CreateNewTrade(response.POST)
                        if form.is_valid():
                                n = form.cleaned_data["name"]
                                t = AssetList(name=n) #t created here
                                t.save()
                                response.user.assetlist.add(t)
        
                        return HttpResponseRedirect("/userdash/%i" %t.id) #here we are outside the if statement`
        

        建议修复

        `def create(response):
                #response.user
                if response.method == "POST":
                        form = CreateNewTrade(response.POST)
                        if form.is_valid():
                                n = form.cleaned_data["name"]
                                t = AssetList(name=n) #t created here
                                t.save()
                                response.user.assetlist.add(t)
                                return HttpResponseRedirect("/userdash/%i" %t.id) #here t is defined but your code will not handle if if response.method == "POST" but form is not valid.`
        

        如果你愿意,尝试处理 if 语句失败(对不起,我的标签系统,所以不会接受它作为代码,不知道为什么)

        `def create(response):
            #response.user
            if response.method == "POST":
                form = CreateNewTrade(response.POST)
                if form.is_valid():
                    n = form.cleaned_data["name"]
                    t = AssetList(name=n) #t created here
                    t.save()
                    response.user.assetlist.add(t)
                    return HttpResponseRedirect("/userdash/%i" %t.id) 
                else:
                    #handle if inner if fails`
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-10-31
          • 2020-05-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-02
          • 2011-11-06
          相关资源
          最近更新 更多