khashashin
khashashin

Reputation: 1127

Combine DRF router with django urlpattern

How can I combine together django urlpatterns with DRF router using app_name = 'scrumboard'? I tried all ways that are in DRF documentation explaned but still can't resolve this problem. So far I have following urls.py file:

#scrumboard/urls.py

from rest_framework.routers import DefaultRouter
from .api import ListViewSet, CardViewSet
from django.urls import re_path, path, include
from . import views

router = DefaultRouter()
router.register(r'lists', ListViewSet)
router.register(r'cards', CardViewSet)

app_name = 'scrumboard'
urlpatterns = [
    path('', views.index, name="index"),
    re_path(r'^api/', include((router.urls))),
]

This is my project urls.py:

#project/urls.py

from django.contrib import admin
from django.urls import include, path, re_path
#Add URL maps to redirect the test URL to our application
from django.views.generic import RedirectView
# Use static() to add url mapping to serve static files during development (only)
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('', include('home.urls')),
    path('admin/', admin.site.urls),
    path('accounts/', include('django.contrib.auth.urls')),
    path('test/', RedirectView.as_view(url='/catalog/', permanent=True)),
    path('polls/', include('polls.urls')),
    path('blog/', include('blog.urls')),
    path('catalog/', include('catalog.urls')),
    path('scrumboard/', include('scrumboard.urls'))
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

In my template I will have an opportunity to define dynamic url like so:

<li><a href="{% url 'scrumboard:index' %}">Scrumboard</a></li>

which will take me to my Scrumboard app.

With this code above when I go to this url localhost:8000/scrumboard/ I get an Error

enter image description here

UPDATE

When I go to localhost:8000/scrumboard/api it works well

enter image description here

UPDATE

Full Traceback http://dpaste.com/07QR05W

UPDATE

Added project urls.py code

Upvotes: 2

Views: 2767

Answers (3)

leodotcloud
leodotcloud

Reputation: 1960

In my case, I was using Django Rest Framework with Default Router in app1. The following way of defining extra_kwargs fixed the error.

# app1/serializers.py
from rest_framework import serializers
from app1.models import User

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username')
        extra_kwargs = {
            'url': {'view_name': 'app1:user-detail'},name
        }

Upvotes: 0

khashashin
khashashin

Reputation: 1127

I just wanted to delete this question, but I thought maybe someone else would come up against this and decided to describe what the problem really was.

Because of my insufficient experience, I was looking for a problem in the wrong place.

By following the link on the home page template:

<li><a href="{% url 'scrumboard:index' %}">Scrumboard</a></li>

#scrumboard/urls.py

from django.urls import re_path, path, include
from . import views

app_name = 'scrumboard'
urlpatterns = [
    path('', views.index, name="index"),
]

we ran a function defined in view.py that takes this request and renders template under scrumboard/index.html

#scrumboard/views.py

def index(request):
    return render(request, 'scrumboard/index.html', {})

And here flies the error.

Exception Type: NoReverseMatch at /scrumboard/
Exception Value: Reverse for 'lists' not found. 'lists' is not a valid view function or pattern name.

I used django Reversing namespaced URLs since I have several applications and every application has his own index.html template. I had to guess that the problem lies somewhere in this template:

{% extends 'base.html' %}
{% load static %}


{% block title %}
    <title>Scrumboard</title>
{% endblock %}
{% block extracss %}
    <link rel="stylesheet" href="{% static 'scrumboard/css/main.css' %}" />
{% endblock %}

{% block content %}
        <a href="{% url 'scrumboard:lists' %}" target="_blank" class="top-menu">Lists</a><br>
        <a href="{% url 'scrumboard:cards' %}" target="_blank" class="top-menu">Cards</a>
        <hr>
          <div ng-app="scrumboard.demo">
            {% verbatim %}
            <div ng-controller="ScrumboardController">
              <div ng-repeat="list in data">
                <h3>{{list.name}}</h3>
                <ul>
                  <li ng-repeat="card in list.cards">{{card.title}}</li>
                </ul>
                <div class="input-group">
                  <input type="text" ng-model="new_title">
                  <button class="btn btn-outline-secondary" ng-click="add(list, new_title)">+</button>
                </div>
              </div>
            </div>
            {% endverbatim %}
              <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
              <script type="text/javascript" src="{% static 'scrumboard/js/scrumboard.js' %}"></script>
          </div>
{% endblock %}

Seeing these lines, I thought that the problem is probably in this:

<a href="{% url 'scrumboard:lists' %}" target="_blank" class="top-menu">Lists</a><br>
<a href="{% url 'scrumboard:cards' %}" target="_blank" class="top-menu">Cards</a>

And I decided to just comment them. And after thinking that the problem was solved, I reloaded the page but the error still flew out again.

<!-- <a href="{% url 'scrumboard:lists' %}" target="_blank" class="top-menu">Lists</a><br>
<a href="{% url 'scrumboard:cards' %}" target="_blank" class="top-menu">Cards</a> -->

But django ignores the usual html comments and tries to read the commented code. And so my mistake did not go away and I started looking for the problem elsewhere. And because of inexperience I asked an incorrect question. Just deleting this lines solve my problem.

Upvotes: 2

rtindru
rtindru

Reputation: 5337

How do we expect that /scrumboard/ matches the first regex? Is there an outer urls.py file with an include of the one you mentioned?

In the absence of more information, does this work?

urlpatterns = [
    path('^scrumboard/?$', views.index, name="index"),
    re_path(r'^api/', include((router.urls))),
]

Upvotes: 0

Related Questions