python - request.method == POST equaling true in next function causing it to run prematurely - Stack Overflow

so i am running this codedef login_or_join(request):if request.method == "POST":option = req

so i am running this code

def login_or_join(request):

    if request.method == "POST":
        option = request.POST.get("option")
        print('post request recieved')

        if option == "1":
            return login_screen(request)

        if option == '2':
            return in_game(request)

    return render(request,"login_or_join.html")

and def login_screen() looks like this

def login_screen(request):
    if request.method == "POST":
    
        username = request.POST.get("username")
        password = request.POST.get("password")
        print(username)
        print(password)

        user = authenticate(request, username=username, password=password)
    
        print(user)

        if user is not None:
            return redirect('join_lobby')
        else:
            return render(request,'login_page.html',)
    
    return render(request, 'login_page.html')

Whenever I click "option 1" it runs login_screen but in a way I don't want it to. it seems to just follow that request.method == "POST" and prints username and password immediately, meaning it is setting username and password immediately making any log in attempt wrong. But I don't want it to set those (or print them) until I've pressed the button on the next page. Further more when I hit "enter" or "log in" it doesn't reshow the page with the error message, it just goes back login_or_join(). I feel like I am taking crazy pills as I've been working on this website for a while and this is the first time I'm having this kind of issue. I've tried messing with it but feel I've been staring at it too long. Any help would be appreciated!

so i am running this code

def login_or_join(request):

    if request.method == "POST":
        option = request.POST.get("option")
        print('post request recieved')

        if option == "1":
            return login_screen(request)

        if option == '2':
            return in_game(request)

    return render(request,"login_or_join.html")

and def login_screen() looks like this

def login_screen(request):
    if request.method == "POST":
    
        username = request.POST.get("username")
        password = request.POST.get("password")
        print(username)
        print(password)

        user = authenticate(request, username=username, password=password)
    
        print(user)

        if user is not None:
            return redirect('join_lobby')
        else:
            return render(request,'login_page.html',)
    
    return render(request, 'login_page.html')

Whenever I click "option 1" it runs login_screen but in a way I don't want it to. it seems to just follow that request.method == "POST" and prints username and password immediately, meaning it is setting username and password immediately making any log in attempt wrong. But I don't want it to set those (or print them) until I've pressed the button on the next page. Further more when I hit "enter" or "log in" it doesn't reshow the page with the error message, it just goes back login_or_join(). I feel like I am taking crazy pills as I've been working on this website for a while and this is the first time I'm having this kind of issue. I've tried messing with it but feel I've been staring at it too long. Any help would be appreciated!

Share edited Mar 7 at 16:49 CalebatWaterwash asked Mar 7 at 16:16 CalebatWaterwashCalebatWaterwash 531 silver badge5 bronze badges 4
  • 4 You should redirect to the login screen, rather than calling its view function directly. – jasonharper Commented Mar 7 at 17:22
  • 2 Yes, this. Calling another view function directly is very odd. – John Gordon Commented Mar 7 at 17:26
  • I guess I am just not familiar with conventions. I tried making it within the same view but that seems to cause the same problems. I guess a redirect makes sense I was just hoping to keep everything contained in one file and url since it's not going to hold alot of code either way. – CalebatWaterwash Commented Mar 7 at 17:31
  • @CalebatWaterwash: this is not a convention, it is the so-called Post/Redirect/Get architectural pattern. – willeM_ Van Onsem Commented Mar 8 at 9:53
Add a comment  | 

2 Answers 2

Reset to default 2

I guess the problem is that you are calling login_screen with request as parameter. But that variable is the parameter received on login_or_join so is the POST request with the option, neither a GET nor a POST with the username and password.

I think in this case you can just name the url and do:

if option == "1":
    return redirect(login_screen_name)
if option == "2":
    return redirect(in_game_screen_name)

You don't want to let the login screen process the request, but make a new, GET request, to the login_screen, so:

def login_or_join(request):
    if request.method == 'POST':
        option = request.POST.get('option')
        if option == '1':
            return redirect('name-of-login-screen')
        if option == '2':
            return redirect('name-of-in-game-view')
    return render(request, 'login_or_join.html')

where you pass the names of the views defined in the urls.py:

urlpatterns = [
    path('some/path/', login_screen, name='name-of-login-screen'),
    path('some/other/path/', in_game, name='name-of-in-game-view'),
]

This is the so-called Post/Redirect/Get architectural pattern [wiki]. This is also necessary to prevent unexpected behavior when you refresh in the browser. If the request that rendered the response was a POST request, hitting refresh in the browser will make a new POST request, so that means that if the request would for example add an item to a shopping basket, now you have added it twice.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744918298a4600971.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信