Path is missing

Hi

I am using Django Rest Framework for my application. I have set up everything and the login works and I get the login page. But if I go to the register page I get page not found, which I don’t understand because the path is set up correctly.

Here is my main project’s urls.py:

from django.contrib import admin
from django.urls import path, include
from .views import home_view, api_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', home_view),
    path('account/', include('rest_framework.urls')),
    path('companies/', include('businesses.urls')),
    path('page/', include('pages.urls')),
    
]

and here is my accounts urls.py

from django.urls import path
from .views import RegisterView, LoginView
from knox import views as knox_views

urlpatterns = [
    path('register/', RegisterView.as_view(), name='register'),
    path('login/', LoginView.as_view(), name='login'),
    path('logout/', knox_views.LogoutView.as_view(), name='logout'),
    path('logoutall/', knox_views.LogoutAllView.as_view(), name='logoutall'),
]

and this is what the page is showing:

Page not found

Request Method: GET

Request URL: http://127.0.0.1:8000/account/register/

Using the URLconf defined in sobusnet.urls, Django tried these URL patterns, in this order:

  1. admin/
  2. account/ ^login/$ [name=‘login’]
  3. account/ ^logout/$ [name=‘logout’]
  4. companies/
  5. page/

The current path, account/register/, didn’t match any of these.

I have a couple of questions please:

  1. Why on the browser on the page not found page is number 2. in the URL patterns empty?
  2. Why is it using the GET method when in the view I only have a post method?
  3. Why is the register path not found but the login path is?
  4. What is the ^ for in the account/login and logout paths?

Here is my register view:

class RegisterView(GenericAPIView):
    serializer_class = RegisterSerializer

    def post(self, request):
        serializer=RegisterSerializer(data=request.data)

        if serializer.is_valid():
            
            serializer.save()
            return Response(serializer._data, status=status.HTTP_201_CREATED)
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

You have:

Notice that your “account” url is including rest_framework.urls - not your accounts urls.py So it’s not going to look at your urls to find the match.

Ken

Thank you Ken I am bad at this some times in that I do not look properly and then I waste other people’s time with stupid things I could have fixed myself. Thanks for showing where I messed up.

Another question pls: Do I have to create a new post every time I ask a new question or you think we can just keep this thread going?

The advantage of new posts are

  • other people are (perhaps) more inclined to answer than to jump into a long-running thread. (or, that may just be my impression)
  • by putting a good title in the subject, makes it easier for someone else looking for answers find similar questions rather than trying to search through long threads

So I’d say, go ahead and create new posts as needed. (However, if you encounter another urls / path-related issue, I might be tempted to say it should be added it to this one - but that’s just me.)

Technically, it’s the forum’s moderators call, but my opinion is that I’d rather see a new post for each different topic. I don’t see anything posted in the FAQ or the Feedback topic providing any specific guidance - and I really don’t want to bug our already-too-busy-doing-other-things-moderators to raise this as an issue.

Ken

Ok thanks I will make a new post for every new topic. So in the first post in this thread I asked a question about why the method for register is GET when for the view I only have a post method?
Also what the ^ is used for in the path and why is the second path in the list empty. I have seen that before.

I’m really confused by what you’re trying here.

I’m getting the impression that you’re pointing your browser to your account/register view, but you’re showing an API interface.

Or do you have a smart front-end that is trying to use this API?

The caret (^) in the path is used when you use a regex in your path. It indicates that it needs to match starting with the beginning of the string. For example, if you specify a regex path as ‘og/’, it would match someone requesting ‘log/’, because you didn’t anchor the search to the beginning of the string.

Hi Ken

I am trying to build a web app that has a Django back end and then a Vue (and IOS, Android or whatever else I can add) front end. Everything must go through the API so there is no direct connection to the database. I am going to create a Vue front end (one page really) that will get all the information and logic from the back end through the API to display the information.

Ok, but are you trying to point your browser to account/register? If so, that doesn’t make sense here.

Leaving that aside for the moment, to address your question:

The GET you are seeing is a result of a request coming in. Something (I’m assuming a browser, but it could be your app if it’s doing a GET) is issuing a GET request on that URL.

The post you’ve defined in your view is what the view will handle. Since you’re using a class-based interface, you would inherit the default get handler from the parent class. But this definition in your view doesn’t prevent or affect what the browser is sending. All you’re doing here is defining which verbs you’re handling in your code. Everything else will be handled by the default functions.

Here is my main project urls.py:

from django.contrib import admin
from django.urls import path, include
from .views import home_view, api_view, app_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', home_view),
    path('api/', api_view),
    path('accounts/', include('accounts.urls')),
    path('companies/', include('businesses.urls')),
    path('page/', include('pages.urls')),
    path('app/', app_view),
    
]

and here is my accounts urls.py:

from django.urls import path, include
from .views import RegisterView, LoginView, ProfileView, EmailValidationView, VerificationView
from knox import views as knox_views
from django.views.decorators.csrf import csrf_exempt

urlpatterns = [
    path('', include('rest_framework.urls')),
    path('register/', RegisterView.as_view(), name='register'),
    path('login/', LoginView.as_view(), name='login'),
    path('logout/', knox_views.LogoutView.as_view(), name='logout'),
    path('logoutall/', knox_views.LogoutAllView.as_view(), name='logoutall'),
    path('profile/', ProfileView.as_view(), name='profile'),
    path('validate-email', csrf_exempt(EmailValidationView.as_view()), name='validate_email'),
    path('activate/<uidb64>/<token>', VerificationView.as_view(), name='activate_account'),
]

on the main page that is just a static page I have a link that goes to accounts/register. If I click on it it takes me to the Rest Framework provided page and at the top of the page it says register and right below it it says GET /accounts/register and then below that is says HTTP 405 Method Not Allowed. That URL is handled by this view:

class RegisterView(GenericAPIView):
    serializer_class = RegisterSerializer

    def post(self, request):
        serializer=RegisterSerializer(data=request.data)

        if serializer.is_valid():
            
            serializer.save()
            return Response(serializer._data, status=status.HTTP_201_CREATED)
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

So my question is why is the link to accounts/register producing a GET request and how do I make it so that it’s a POST request so the view I created can handle it?

This is an Apples/Oranges issue. If you’re using your browser to go to a page, make it a standard Django view, not an API request.

If you’re writing a Vue component to perform the registration, then it would be appropriate to have Vue access the API.

When you are writing JavaScript (alone or in frameworks like Angular, Vue or React) to interact with the server, that is when it’s appropriate to use the API interfaces. Any time you are looking to use the standard browser interface with HTML, then you only want to use standard views.

(Yes, there are some exceptions in some specialized cases, this isn’t one of them.)

Ok thank you Ken I’m a little confused at this early stage of my learning process. I will get there eventually

No worries, we’re here to help.

Ken

ok I found my mistake and fixed it working now more questions to come. Thanks a lot Ken