глобальная переменная не определена в django - PullRequest
0 голосов
/ 11 июля 2020

У меня проблема с этим кодом в django Я определил две глобальные переменные

Но Django не идентифицирует их

мое мнение:

global phone,rand_num
def phone_login(request):
    if request.method == 'POST':
        form = PhoneLoginForm(request.POST)
        if form.is_valid():
            phone = f"0{form.cleaned_data['phone']}"
            rand_num = randint(1000, 9999)
            api = KavenegarAPI('mytoken!')
            params = { 'sender' : '', 'receptor': phone , 'message' : rand_num }
            api.sms_send(params)
            return redirect('account:verify')

    else :
        form = PhoneLoginForm()
    return render(request,'account/phone_login.html',{'form':form})


def verify(request):
    if request.method == "POST":
        form = VerifyCodeForm(request.POST)
        if form.is_valid():
            if rand_num == form.cleaned_data['code']:
                profile = get_object_or_404(Profile, phone = phone)
                user = get_object_or_404(User,profile__id = profile.id)
                login(request,user)
                messages.success(request,'logged in successfully' , 'success')
                return redirect('popasssts:all_posts')
            else:
                messages.error(request,'your code is wrong','warning')
                
    else:
        form = VerifyCodeForm()
    return render(request,'account/verify.html',{'form' : form})

мои URL:

path('verify/',views.verify,name='verify'),

У меня такая ошибка:

NameError at /account/verify/

name 'rand_num' is not defined

Request Method:     POST
Request URL:    http://127.0.0.1:8000/account/verify/
Django Version:     3.0.7
Exception Type:     NameError
Exception Value:    

name 'rand_num' is not defined

Хочу, чтобы пользователь зашел на сайт после ввода СМС кода.

Ответы [ 2 ]

1 голос
/ 11 июля 2020

Что касается глобальных переменных, вам необходимо поместить ключевое слово global внутри функций и присвоить начальные значения внешним переменным:

phone = ""
rand_num = -1

def phone_login(request):
    global phone, rand_num
    # ...

def verify(request):
    global phone, rand_num
    # ...

При таком подходе значения phone и rand_num распределяются между всеми пользователями приложения. Если у вашего приложения несколько пользователей, лучшим подходом будет сохранение значений в сеансе текущего пользователя:

def phone_login(request):
    if request.method == 'POST':
        # ...

        if form.is_valid():
            # ...

            # Save the values in the session
            request.session["phone"] = phone
            request.session["rand_num"] = rand_num

            # ...


def verify(request):
    if request.method == "POST":
        # ...

        if form.is_valid():
            # Get the values from the session, setting
            # default values in case they don't exist.
            phone = request.session.get("phone", "")
            rand_num = request.session.get("rand_num", -1)

            # ...

Для использования сеансов приложение django.contrib.sessions должно быть включено в списке INSTALLED_APPS файл settings.py проекта Django. Кроме того, это приложение необходимо перенести в базу данных проекта с помощью команды python manage.py migrate.

В официальной Django документации у вас есть дополнительная информация о сессиях.

0 голосов
/ 11 июля 2020

Внимание: Глобальные переменные нарушают, возможно, самый важный принцип программирования - инкапсуляцию. Используя их, ваш код превратится в спагетти. Не используйте их. (Если нет другого способа)

Вот что означает инкапсуляция:

... Инкапсуляция относится к объединению данных с методами, которые работают с этими данными, или ограничивающим прямого доступа к некоторым компонентам объекта.

Источник: Википедия

Если вы действительно хотите его использовать, вот ваша проблема: в функциях должно использоваться ключевое слово global.

Давайте попробуем так:

phone = ""
rand_num = 0

def phone_login(request):
    global phone, rand_num
    if request.method == 'POST':
    ...

def verify(request):
    global phone, rand_num
    if request.method == "POST":
    ...
...