django ссылка на локальную переменную 't' перед присваиванием - PullRequest
0 голосов
/ 07 мая 2020

Я увидел, что это обычная ошибка, и просмотрел другие сообщения, но они мне не помогли.

Я получаю сообщение об ошибке

Exception Value: local variable 't' referenced before assignment

Но моя переменная t равна объявил 3 строки выше, где говорится, что это не так, внутри моей проверки 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.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, чтобы мой оператор возврата принял ее?

Ответы [ 3 ]

0 голосов
/ 07 мая 2020

Что должна возвращать ваша функция create, если форма недействительна?

Если форма недействительна, вы ссылаетесь на значение переменной t, которой не существует. Вы должны создать эту переменную вне if (если вы хотите вернуть значение по умолчанию) или вернуть пользователю ошибку, если форма недействительна.

0 голосов
/ 07 мая 2020

здесь вы определили t внутри оператора if, но это не гарантирует, что он всегда будет выполняться, поэтому существует вероятность отсутствия переменной 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`
0 голосов
/ 07 мая 2020

Это потому, что ваша форма недействительна. Таким образом, он будет напрямую 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)

См. Комментарии выше, чтобы понять, что происходит. Таким образом, возможный редуктор ошибок может быть:

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

Теперь вы определили t=None глобально внутри функции, она не будет показывать ошибку, которую показывала раньше. Но проблема все равно будет, потому что t это None. Значит, у него не будет атрибута 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

Надеюсь, вы поняли, в чем проблема.

...