anonymus13
anonymus13

Reputation: 13

Why Django does not generate app name into href paths?

I hope someone could maybe help me, please : I am quite new to Django and currently trying to implement a simple login/logout for a test page. However, for some reasons, the Django does not generate the name of application in the href (so where it should be xxxx/main/register, it is only xxx/register). But when I put the app name manually in the href in Pycharm, it generates it two times (so it becomes xxx/main/main/register).

So for this:

<a href="/logout/">Logout</a>

I got this url: http://127.0.0.1:8000/logout/

If I write this:

<a href="main/logout/">Logout</a>

I got this url: http://127.0.0.1:8000/main/main/logout/

But I need to get this: http://127.0.0.1:8000/main/logout/

It worked before, but from one minute to another, it suddenly stopped directing to the good path. And django does the same thing with every links in my site.

main/urls.py:

from django.urls import path
from . import views

app_name = 'main'  # here for namespacing of urls.

urlpatterns = [
    path("", views.homepage, name="homepage"),
    path("register/", views.register, name="register" ),
    path("logout/", views.logout_request, name="logout"),
]

main/views.py:

from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import Tutorial
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import logout, authenticate, login
from django.contrib import messages

def homepage(request):
    return render(request = request,
                  template_name='main/home.html',
                  context = {"tutorials":Tutorial.objects.all})

def register(request):
    if request.method == "POST":
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f"New account created: {username}")
            login(request, user)
            return redirect("main:homepage")
        else:
            for msg in form.error_messages:
                messages.error(request, f"{msg}: {form.error_messages[msg]}")
    else:
        form = UserCreationForm
    return render(request = request,
              template_name='main/register.html',
              context={"form":form})

def logout_request(request):
    logout(request)
    messages.info(request, "Logged out successfully!")
    return redirect("main:homepage")

mysite/urls.py:

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('main/', include('main.urls')),
    path('admin/', admin.site.urls),
    path('tinymce/', include('tinymce.urls')),
]

Upvotes: 1

Views: 715

Answers (3)

ludel
ludel

Reputation: 91

You should use the url name in the template. It should solve the problem. Like this: <a href="{% url 'logout' %}">Logout</a>

Or with namespacing: <a href="{% url 'main:logout' %}">Logout</a>

Upvotes: 0

bruno desthuilliers
bruno desthuilliers

Reputation: 77912

The behaviour you observe has nothing to do with Django, it's a basic html feature: in the first case you're using an absolute path (=> starting with a slash) for your href, in the second one you're using a relative path (NOT starting with a slash) so it's resolved relatively to the current url path whatever it is. You'd have the very same issue with plain static HTML.

This being said, in Django, you should never hardcode urls, but use the {% url <name> %} template tag (or the django.utils.reverse() function in Python code) instead, so you can change your urls in the urls.py files without breaking anything.

Upvotes: 1

Ramanjaneyalu T
Ramanjaneyalu T

Reputation: 36

<a href="{% url 'logout' %}">

Use the name in href tag that will work.

Upvotes: 0

Related Questions