Vi que era un error común y busqué en otra publicación, pero no me ayudaron.

Estoy recibiendo el error

Exception Value: local variable 't' referenced before assignment

Pero mi variable t se declara 3 líneas arriba donde dice que no, dentro de mi validación if. El alcance debería estar bien para mi regreso.

Función en cuestión:

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

Código completo:

$ 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 %}

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

¿Cómo asigno mi variable t para que mi declaración de devolución la acepte?

0
brad 7 may. 2020 a las 06:31

3 respuestas

La mejor respuesta

Es porque su formulario no es válido. Por lo tanto, irá directamente a la parte de retorno HttpResponseRedirect, donde t no está definido.

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)

Vea los comentarios anteriores para comprender lo que está sucediendo. Entonces, el posible reductor de errores podría ser:

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

Ahora, ha definido t=None globalmente dentro de la función, no mostrará el error que mostraba antes. Pero, todavía habrá problemas porque t es None. Por lo tanto, no tendrá ningún atributo id. Por lo tanto, se mostrará has no attribute DoesNotExist. Por lo tanto, debe pensar qué hacer si el formulario no es válido, dónde redireccionar.

O bien, puede resolver el problema con la instrucción else si el formulario no es válido. Me gusta:

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

Ahora, espero que hayas entendido cuál era el problema.

0
Biplove Lamichhane 7 may. 2020 a las 03:53

¿Cuál debería ser la devolución de su función create si el formulario no es válido?

Si el formulario no es válido, está haciendo referencia al valor de una variable t que no existe. Debe crear esta variable fuera del if (si desea devolver un valor predeterminado) o devolver un error al usuario si el formulario no es válido.

0
arthursribeiro 7 may. 2020 a las 03:38

Aquí definió t dentro de la instrucción if pero no garantiza que siempre se ejecute, por lo que existe la posibilidad de que no haya una variable t (si la instrucción if falla). t también es una variable local de la declaración if y no se puede usar fuera de ella (a menos que sea algo debajo de la declaración 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`

Arreglo sugerido

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

Intente manejar la declaración if falla si lo desea (lo siento por mi sistema de tabulación, así que no lo aceptaré como un código, no estoy seguro de por qué)

`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
HardBoiledPotato 7 may. 2020 a las 03:45