简体   繁体   English

赋值前引用的 django 局部变量 't'

[英]django local variable 't' referenced before assignment

I saw this was a common error and I did look through other post, but they did not help me.我看到这是一个常见错误,我确实查看了其他帖子,但他们没有帮助我。

I am getting the error我收到错误

Exception Value: local variable 't' referenced before assignment

But my t variable is declared 3 lines above where it is saying it is not, inside my if validation.但是我的 t 变量在我的 if 验证中被声明为高于它所说的 3 行。 Scope should be fine for my return. Scope 应该适合我的回归。

function in question: function 有问题:

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

complete code:完整代码:

$ cat userdash/views.py $ 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 $ 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 $ 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 %}

error:错误:

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']

How do I assign my t variable so my return statement will accept it?如何分配我的 t 变量,以便我的 return 语句接受它?

It is because your form is not valid.这是因为您的表格无效。 So, it will directly go to the return HttpResponseRedirect part, where t is not defined.因此,它将直接 go 到返回的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)

See comments above to understand what's going on.请参阅上面的评论以了解发生了什么。 So, possible error reducer could be:因此,可能的错误减少器可能是:

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

Now, you have defined t=None globally inside function, it will not show the error it was showing before.现在,您已经在 function 中全局定义了t=None ,它不会显示之前显示的错误。 But, there will still be problem because t is None .但是,仍然会有问题,因为tNone So, it won't have any attribute id .所以,它不会有任何属性id Hence, has no attribute DoesNotExist will be shown.因此,将显示has no attribute DoesNotExist Therefore, you have to think that what to do if form is not valid, where to redirect.因此,您必须考虑如果表单无效该怎么办,重定向到哪里。

Or, you can deal with the problem with else statement if form is not valid.或者,如果表单无效,您可以使用 else 语句处理问题。 Like:喜欢:

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

Now, I hope you understood what was the problem.现在,我希望您了解问题所在。

What should your create function return is the form is invalid?create的 function 应该返回什么表格无效?

If the form is invalid you're referencing the value of a t variable that doesn't exists.如果表单无效,您将引用不存在的t变量的值。 You should create this variable outside the if (if you want to return a default value) or return an error to the user if the form is invalid.您应该在 if 之外创建此变量(如果您想返回默认值),或者如果表单无效,则向用户返回错误。

here you defined t inside the if statement but it doesn't guarantee to always run so there is a chance that there is no t variable(if the if statement failed).在这里,您在 if 语句中定义了 t 但它不能保证始终运行,因此有可能没有 t 变量(如果 if 语句失败)。 t is also a local variable of the if statement and can't be used outside of it(unless its something under the if statement). 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`

suggested fix建议修复

`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.`

try handling the if statement fails if you want(sorry for my tabbing system, SO wont accept it as a code not sure why)如果你愿意,尝试处理 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`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM