can't use reverse url function in django - django

tests.py
from django.test import TestCase
from django.urls import reverse
from rest_framework import status
from .models import User
class UserCreateAPIViewTestCase(APITestCase):
def setUp(self):
super().setUp()
self.url = reverse("admins")
def test_user_creating(self):
user_data = {}
response = self.client.post(self.url, user_data, format="json")
self.assertEqual(response.status_code,
status.HTTP_403_FORBIDDEN)
2.urls.py
from django.urls import path
from django.conf.urls import include
from rest_framework_nested.routers import SimpleRouter
from apps.users.views import (
CreateProviderViewSet,
LoginViewSet,
UserViewSet,
ProviderViewSet,
ClientViewSet,
LoginAsViewSet
)
app_name = 'users'
router = SimpleRouter(trailing_slash=False)
router.register("admins", UserViewSet, base_name='admins')
router.register("providers", ProviderViewSet, base_name='providers')
router.register("clients", ClientViewSet, base_name='clients')
router.register("login", LoginViewSet, base_name='auth')
router.register("login-as", LoginAsViewSet)
urlpatterns = [
path('', include(router.urls)),
]
when I run python .\manage.py test apps.users.tests
This error occurs
ERROR: test_user_creating (apps.users.tests.UserCreateAPIViewTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\vu.tran\Desktop\kona-server\apps\users\tests.py", line 19, in setUp
self.url = reverse("admins")
File "C:\Users\vu.tran\Desktop\kona-server\env\lib\site-packages\django\urls\base.py", line 90, in reverse
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "C:\Users\vu.tran\Desktop\kona-server\env\lib\site-packages\django\urls\resolvers.py", line 668, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'admins' not found. 'admins' is not a valid view function or pattern name.
my structure folders like this my folders
I wonder why cannot get reverse("admins")
Do you have any idea?

According to the documentation, if you want to access the list view, the name for the url should be admins-list. The name of the argument for your register function may also be basename instead of base_name.

Related

ImproperlyConfigured error when using pyrebase with Django

I tried to import pyrebase in my views.py, but I've got an error raisen:
Exception in thread django-main-thread:
Traceback (most recent call last):
File "C:\Users\USER\Documents\python projects\yerekshe\lib\site-packages\django\urls\resolvers.py", line 581, in url_patterns
iter(patterns)
TypeError: 'module' object is not iterable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
raise ImproperlyConfigured(msg.format(name=self.urlconf_name))
django.core.exceptions.ImproperlyConfigured: The included URLconf 'yerekshe.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.
here is my views.py:
from django.shortcuts import render, redirect
from .forms import UserForm, UserProfileInfoForm, UpdateProfileForm
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from . import forms
import pyrebase
config = {
'apiKey': "0",
'authDomain': "yerekshe.firebaseapp.com",
'databaseURL': "https://yerekshe.firebaseio.com",
'projectId': "yerekshe",
'storageBucket': "",
'messagingSenderId': "0",
}
firebase = pyrebase.initialize_app(config)
auth = firebase.auth()
def home(request):
return render(request, 'home.html')
def signIn(request):
return render(request, 'login.html')
def postsign(request):
email = request.POST.get('email')
passw = request.POST.get("pass")
try:
user = auth.sign_in_with_email_and_password(email, passw)
except:
message = "invalid cerediantials"
return render(request, "login.html", {"msg": message})
print(user)
return render(request, "home.html", {"e": email})
and here is yerekshe\urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('account/', include('account.urls'))
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

How to turn a variable into a module with sys.modules hack?

import os
from glob import glob
from importlib import import_module
from django.urls import re_path as _re_path, path as _path
def _glob_init(name):
name = name.replace('.', os.sep)
path = os.sep + '**'
modules = []
for module in glob(name + path, recursive=True):
importable = os.path.splitext(module)[0].replace(os.sep, '.')
if '__' in importable:
continue
try:
module = import_module(importable)
except ModuleNotFoundError:
module = import_module(importable[:-1])
modules.append(module)
return modules
class UrlManager:
def __init__(self, views_root):
self.views_root = views_root
self._url_patterns = []
def _path(self, route, kwargs=None, name=None, is_re=None):
func = _re_path if is_re else _path
def decorator(view):
_view = view # keep the original view
if isinstance(view, type):
view = view.as_view()
self._url_patterns.append(
func(route, view, kwargs=kwargs, name=name or view.__name__)
)
return _view
return decorator
def path(self, route, kwargs=None, name=None):
return self._path(route, kwargs=kwargs, name=name, is_re=False)
def re_path(self, route, kwargs=None, name=None):
return self._path(route, kwargs=kwargs, name=name, is_re=True)
#property
def url_patterns(self):
if isinstance(self.views_root, str):
_glob_init(self.views_root)
else:
for root in self.views_root:
_glob_init(root)
return self._url_patterns
Basic usage:
# app.urls.py
app_urls = UrlManager('app.views')
# app.views.py
from models import SomeModel
from urls import app_urls
#app_urls.path('foo/', name='foo')
def view(request):
return response
# project.urls.py
from django.urls import include
from app.urls import app_urls
urlpatterns = [
path('', include(app_urls.urlpatterns))
]
Okay, now:
Everything works when you already have the migrations up and running, but when you want to create a new migration; due the fact that this code flow is something like:
--project urls.py imports app.urls
--app.urls imports views
--views imports models
--models doesn't exist yet because this is a migration command run
--error
I need to somehow either create a module named the instance so I can use include('module.urls') or some other way to postpone the imports.
Repo is at https://github.com/isik-kaplan/django_urls if anyone wants to open a pr.

Problem with django-RESTframework-Tutorial

I'm trying to get familiar with django-RESTframeworks, therefore I started the official tutorial, to create a Test-API.
https://www.django-rest-framework.org/tutorial/quickstart/#quickstart
When finally starting the API on my Windows via [CMD] "pyhon manage.py runserver", I get an error code on the command line, which you will see below.
I also want to add, that unfortunately, there is some ambiguity in the descriptions in the tutorial, at least from the viewpoint of a beginner, i.e. it's not always certain whether the corresponding code in the tutorial
needs to be added in a module or replace all or part of the code in the modules.
Therefore, I tried implementing the directions of the tutorial in various ways, always with the same end result.
I'm running the code in a virtual env, where i've installed Django 1.11., so there shouldn't be an issue with different Django versions.
C:\Users\Rolimar\projects\djREST_tut>workon djresttut
(djresttut) C:\Users\Rolimar\projects\djREST_tut>python manage.py runserver
Performing system checks...
Unhandled exception in thread started by <function wrapper at 0x0000000004CBF978>
Traceback (most recent call last):
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\utils\autoreload.py", line 228, in wrapper
fn(*args, **kwargs)
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\core\management\commands\runserver.py", line 124, in inner_run
self.check(display_num_errors=True)
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\core\management\base.py", line 359, in check
include_deployment_checks=include_deployment_checks,
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\core\management\base.py", line 346, in _run_checks
return checks.run_checks(**kwargs)
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\core\checks\registry.py", line 81, in run_checks
new_errors = check(app_configs=app_configs)
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\core\checks\urls.py", line 16, in check_url_config
return check_resolver(resolver)
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\core\checks\urls.py", line 26, in check_resolver
return check_method()
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\urls\resolvers.py", line 256, in check
for pattern in self.url_patterns:
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\utils\functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\urls\resolvers.py", line 407, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\utils\functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Users\Rolima\Envs\djresttut\lib\site-packages\django\urls\resolvers.py", line 400, in urlconf_module
return import_module(self.urlconf_name)
File "c:\python27\Lib\importlib\__init__.py", line 37, in import_module
__import__(name)
File "C:\Users\Rolima\projects\djREST_tut\tutorial\urls.py", line 19, in <module>
from django.urls import include, path
ImportError: cannot import name include
And here my codes, I tried to copy from the tutorial:
"serializers.py"
from django.contrib.auth.models import User, Group
from rest_framework import serializers
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email', 'groups')
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ('url', 'name')
"views.py"
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
# Create your views here.
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from tutorial.quickstart.serializers import UserSerializer, GroupSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
"urls.py"
"""tutorial URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from django.urls import include, path
from rest_framework import routers
from tutorial.quickstart import views
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
in "settings.py", where I added 'rest_framework'
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles'
'rest_framework',
]
and where I also added the following code in the very end:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
Most probably you are using django<2.0 but following tutorials which are written in django>2.0. From django 2.0, include has been moved to django.urls, before it resided in django.conf.urls(changelog reference). So you need to update your urls.py like this:
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework import routers
from tutorial.quickstart import views
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
You can't use path as well, because it was introduced in django 2 as well.
Or you can move to django>2.0, but in that case you have to remove from django.conf.urls import url and use from django.urls import url.

DRF - how to reverse a class based view in api_root

In Django REST Framework, I'm trying to add an API root to a views.py that has class based views.
Error:
$ http http://127.0.0.1:8000/api/
Error - django.urls.exceptions.NoReverseMatch: Reverse for 'SnippetListView' not found. 'SnippetList' is not a valid view function or pattern name.
backend/views.py
from backend.models import *
from backend.serializers import *
from rest_framework import generics
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
#api_view(['GET'])
def api_root(request, format=None):
return Response({
'snippets': reverse('SnippetList')
# 'snippets': reverse('SnippetListView')
# 'snippets': reverse('snippet-list')
# 'snippets': reverse('snippet_list')
})
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
backend/urls.py
from backend import views
from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
path('', views.api_root),
path('snippets/', views.SnippetList.as_view()),
path('snippets/<int:pk>/', views.SnippetDetail.as_view()),
]
Docs:
https://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/#creating-an-endpoint-for-the-highlighted-snippets
You need to name the view url in order to use the reverse.
#urls.py
path('snippets/', views.SnippetList.as_view(), name='snippet-list'),
#views.py
'snippets': reverse('snippet-list', request=request, format=format)
The tutorial did not originally give names to the urls of the class based views.

host-specific request breaks unrelated test cases

I have the following tests:
from django.test import TestCase
from django.core.urlresolvers import reverse
class TestA(TestCase):
def test_a(self):
reverse('view1')
class TestB(TestCase):
def test_b(self):
self.client.get('/view2/', HTTP_HOST='second.test.net')
class TestC(TestCase):
def test_c(self):
reverse('view1')
TestA and TestB run successfully, but TestC breaks with
..E
======================================================================
ERROR: test_c (dhtest.tests.test_view2.TestC)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/phihag/dhtest/dhtest/tests/test_view2.py", line 14, in test_c
reverse('view1')
File "/home/phihag/.local/share/virtualenvs/dhtest---IwXRQ3/lib/python3.6/site-packages/django/urls/base.py", line 91, in reverse
return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "/home/phihag/.local/share/virtualenvs/dhtest---IwXRQ3/lib/python3.6/site-packages/django/urls/resolvers.py", line 497, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'view1' not found. 'view1' is not a valid view function or pattern name.
----------------------------------------------------------------------
Ran 3 tests in 0.006s
FAILED (errors=1)
But when I comment out TestB, TestC works! How do I fix this problem?
I'm using django-hosts with the following configuration:
from django.conf import settings
from django_hosts import patterns, host
host_patterns = patterns(
'',
host(
r'second\.test\.net',
'dhtest.secondurls',
name='second'
),
host(
r'(\w+)',
'dhtest.urls',
name='default'
),
)
and fairly simple URL files:
# dhtest/urls.py
from django.conf.urls import url
from django.http import HttpResponse
urlpatterns = [
url(r'^view1/', lambda _: HttpResponse('This is view1'), name='view1'),
]
# dhtest/secondurls.py
from django.conf.urls import url
from django.http import HttpResponse
urlpatterns = [
url(r'^view2/', lambda _: HttpResponse('view2 on another host')),
]
For reference, here is the full project.
This is a bug in Django-hosts. In its response middleware, django-hosts clobbers the thread-wide urlconf to that of the request.
In production, that is not a problem, because Django resets the urlconf to the default for every request, or the request-specific one.
But during the tests, after TestB there are no more requests coming, and reverse (and a bunch of other URL-related functions) are using the urlconf for a different host.
To work around this, restore the urlconf after any requests to specific hosts, like this:
class TestB(TestCase):
def test_b(self):
self.client.get('/view2/', HTTP_HOST='second.test.net')
def tearDown(self):
from django.urls.base import set_urlconf
set_urlconf(None)