API Root doesn't have has_permissions with JWT_Authentication - django

Trying to implement djangorestframework_simplejwt in accordance with DRF. After implementing everything based on: https://simpleisbetterthancomplex.com/tutorial/2018/12/19/how-to-use-jwt-authentication-with-django-rest-framework.html and when I'm logged in on localhost:8000, the API Root view is unavailable and the error is an attribute error.
'JWTAuthentication' object has no attribute 'has_permission'
When I view the ModelViewSets themselves, they appear perfectly fine. It's just the API Root itself. When I logout and try to access the API Root, the page loads perfectly fine returning HTTP 403.
Am I not supposed to access the API root when logged in or is there a loophole that I can implement (or extend) in views.py?
Edit:
Internal Server Error: /api/
Traceback (most recent call last):
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\django\core\handlers\exception.py", line 3
4, in inner
response = get_response(request)
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\django\core\handlers\base.py", line 115, i
n _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\django\core\handlers\base.py", line 113, i
n _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\django\views\decorators\csrf.py", line 54,
in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\django\views\generic\base.py", line 71, in
view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\rest_framework\views.py", line 495, in dis
patch
response = self.handle_exception(exc)
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\rest_framework\views.py", line 455, in han
dle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\rest_framework\views.py", line 483, in dis
patch
self.initial(request, *args, **kwargs)
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\rest_framework\views.py", line 401, in ini
tial
self.check_permissions(request)
File "C:\Users\yoom\Code\test\qrveltest\venv\lib\site-packages\rest_framework\views.py", line 334, in che
ck_permissions
if not permission.has_permission(request, self):
AttributeError: 'JWTAuthentication' object has no attribute 'has_permission'
[19/Jun/2019 14:52:38] "GET /api/ HTTP/1.1" 500 95529
Here's the views.py:
from django.views.generic import ListView
from rest_framework import viewsets
from .serializers import *
from django_filters import rest_framework as filters
from rest_framework.permissions import IsAuthenticated
class HomePageView(ListView):
model = Test
template_name = 'home.html'
class UserViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated, )
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_fields = ('username', 'email')
class TestViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated, )
queryset = Test.objects.all()
serializer_class = TestSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_fields = ('id', 'author')
def get_queryset(self):
queryset = Test.objects.all()
username = self.request.user
if username is not None:
queryset = queryset.filter(author__username=username)
return queryset
and urls.py:
from django.urls import path, include
from rest_framework import routers
from .views import *
from rest_framework_simplejwt import views as jwt_views
router = routers.DefaultRouter()
router.register('users', UserViewSet)
router.register('test', TestViewSet)
urlpatterns = [
path('', HomePageView.as_view(), name='home'),
path('api/', include(router.urls)),
path('api/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'),
]

I had the same issue and solved thanks for the comments. If anyone else is having this issue I'll write it here for you. Most likely an error in your settings be sure to add JWT under Authentication default and not Permission e.g.:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}

Related

How do I view the profile of the authenticated user in Django Rest Framework using the Token

I am learning DRF and creating a simple DRF app that lets user login, and view the profile and update the profile. I am using Django's default User model and using Knox for Token Authentication (if it can be done easier using Django Rest Authentication, please let me know and also tell me the procedure).
I have successfully created the API to register and login the user which works fine, but I am stuck at showing the profile to the Authenticated User through a Token.
I am only one Model that is Details which acts as to store the Profile details of the user. I have LoginSerializer which is connected to Login API and MainUserSerializer & UserSerializer, both of which are connected to User API (which acts to show the Profile details on frontend).
I have tried a lot, searched everywhere, but all they show is how to authenticate the user with token through a url (some thing like using curl https://localhost:8000/api/user... etc.), postman, somehing like http post -a... command in terminal and other ways, but I don't want to test or implement using these ways. I want something that if I open my user profile url after logging in the user using the link localhost:8000/user, then at the backend it should do like following as mentioned here enter link description here:
import requests
url = 'http://127.0.0.1:8000/hello/'
headers = {'Authorization': 'Token 9054f7aa9305e012b3c2300408c3dfdf390fcddf'}
r = requests.get(url, headers=headers)
I have tried really hard, but I am unable to successfully go to the details page by authenticating user via token.
My models.py is:
from django.db import models
# Create your models here.
from django.contrib.auth.models import User
class Detail(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
file = models.FileField(verbose_name="CSV File", upload_to='csv_files')
file_desc = models.TextField("CSV File Description")
def __str__(self):
return ("{} ({} {})".format(self.user.email, self.user.first_name, self.user.last_name))
def __unicode__(self):
return (self.file_desc)
My serializers.py is:
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from .models import Detail
from rest_framework import serializers
class MainUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email',)
class UserSerializer(serializers.ModelSerializer):
usr = MainUserSerializer()
class Meta:
model = Detail
fields = ['usr', 'file', 'file_desc']
class LoginSerializer(serializers.Serializer):
email = serializers.EmailField()
password = serializers.CharField()
def validate(self, data):
user = authenticate(**{'username': data['email'], 'password': data['password']})
if user and user.is_active:
return user
raise serializers.ValidationError('Incorrect Credentials Passed.')
My views.py is:
import requests
from rest_framework import permissions
from knox.models import AuthToken
from .serializers import UserSerializer, LoginSerializer
from django.shortcuts import redirect
from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.views import APIView
from django.urls import reverse
from django.http import HttpResponseRedirect
class LoginAPIHTML(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'accounts/login.html'
def get(self, request):
serializer = LoginSerializer()
return Response({'serializer': serializer})
def post(self, request):
serializer = LoginSerializer(data=request.data)
if not serializer.is_valid():
return Response({'serializer': serializer})
user = serializer.validated_data
url = 'http://' + str(request.get_host()) + str(reverse('user', args=None))
headers = {
'Authorization': 'Token ' + str(AuthToken.objects.create(user)[1])
}
r = requests.get(url, headers=headers, format='json')
return HttpResponseRedirect(r)
My urls.py is:
from django.urls import path, include
from .views import LoginAPIHTML
urlpatterns = [
path('api/v1/', include('knox.urls')),
path('login', LoginAPIHTML.as_view(), name='login'),
path('user', UserAPI.as_view(), name='user'),
]
and below is my settings.py:
INSTALLED_APPS = [
'accounts',
'rest_framework',
'rest_framework.authtoken',
'knox',
...
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'knox.auth.TokenAuthentication',
]
}
REST_AUTH_TOKEN_MODEL = 'knox.models.AuthToken'
REST_AUTH_TOKEN_CREATOR = 'project.apps.accounts.utils.create_knox_token'
Whenever, I put the correct credentials in the Login API at localhost:8000/login, then instead of redirecting to the details page at localhost:8000/user, I get the following error:
TypeError at /login
quote_from_bytes() expected bytes
Request Method: POST
Request URL: http://127.0.0.1:8000/login
Django Version: 4.0.3
Exception Type: TypeError
Exception Value:
quote_from_bytes() expected bytes
Traceback Switch to copy-and-paste view
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py, line 55, in inner
response = get_response(request) …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py, line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\decorators\csrf.py, line 54, in wrapped_view
return view_func(*args, **kwargs) …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\base.py, line 84, in view
return self.dispatch(request, *args, **kwargs) …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py, line 509, in dispatch
response = self.handle_exception(exc) …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py, line 469, in handle_exception
self.raise_uncaught_exception(exc) …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py, line 480, in raise_uncaught_exception
raise exc …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py, line 506, in dispatch
response = handler(request, *args, **kwargs) …
Local vars
C:\Users\Khubaib Khawar\Downloads\Meistery\Round2\backend_dev_trial_ass_r2\accounts\views.py, line 202, in post
return HttpResponseRedirect(r) …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\django\http\response.py, line 538, in __init__
self["Location"] = iri_to_uri(redirect_to) …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\site-packages\django\utils\encoding.py, line 139, in iri_to_uri
return quote(iri, safe="/#%[]=:;$&()+,!?*#'~") …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\urllib\parse.py, line 870, in quote
return quote_from_bytes(string, safe) …
Local vars
C:\Users\Khubaib Khawar\AppData\Local\Programs\Python\Python310\lib\urllib\parse.py, line 895, in quote_from_bytes
raise TypeError("quote_from_bytes() expected bytes") …
Local vars
I am fed up of this. It would be better if it sets up either using Knox or using Django Rest Authentication.
This should be of help:
https://studygyaan.com/django/django-rest-framework-tutorial-register-login-logout
I use this has a guide anytime am using Knox with drf.
Looking at the error logs you posted:
Local vars C:\Users\Khubaib Khawar\Downloads\Meistery\Round2\backend_dev_trial_ass_r2\accounts\views.py, line 202, in post return HttpResponseRedirect(r) …
HttpResponseRedirect expects the url or endpoint to be redirected to.
But the variable r is returning a response from the GET request made at:
r = requests.get(url, headers=headers, format='json')
hence the error:
raise TypeError("quote_from_bytes() expected bytes") …
I think this is similar to :
TypeError: quote_from_bytes() expected bytes after redirect
Based on your second comment:
you could try based off your code:
from rest_framework.response import Response
....
r = requests.get(url, headers=headers, format='json')
return Response(r.json(), status=status.HTTP_200_OK)
or
You could try separating your login view from your profile view. There is something called single responsibility in
SOLID principle. your login view should authenticate the user and return a valid token. And your profile view should be a protected view
that requires the user to be authenticated and has the right permission to view his user profile.
your profile view would look like this:
from rest_framework import mixins, authentication, permissions, status, viewsets
from rest_framework.response import Response
from core import models
from users.serializers import UserProfileSerializer
class UserProfileViewSet(viewsets.GenericViewSet,
mixins.ListModelMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
):
"""User profile endpoint"""
authentication_classes = (authentication.TokenAuthentication, )
permission_classes = (permissions.IsAuthenticated,)
queryset = models.UserProfile.objects.all()
serializer_class = UserProfileSerializer
def get_queryset(self):
return models.UserProfile.objects.filter(
user=self.request.user.id)
def perform_create(self, serializer):
return serializer.save(user=self.request.user)
def update(self, request, *args, **kwargs):
user_obj = models.UserProfile.objects.get(id=kwargs['pk'])
user = request.user
if user_obj.user.id == user.id:
serializer = UserProfileSerializer(
user_obj,
data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(
serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
else:
return Response(
'Unauthorized',
status=status.HTTP_401_UNAUTHORIZED)
I hope this helps

django.urls.exceptions.NoReverseMatch: Reverse for 'user-list' not found. 'user-list' is not a valid view function or pattern name

Tutorial 5: Relationship and Hyperlink API Errors
Tutorial link address is:https://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/
I tried query-related solutions, and encountered similar problems on stackoverflow, but after testing, I still couldn't use them.
views.py
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class SnippetDetail(generics.RetrieveDestroyAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly)
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
#api_view(['GET'])
def api_root(request, format=None):
return Response({
'users': reverse('user-list', request=request, format=format),
'snippets': reverse('snippet-list', request=request, format=format),
})
class SnippetHighlight(generics.GenericAPIView):
queryset = Snippet.objects.all()
renderer_classes = [renderers.StaticHTMLRenderer]
def get(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted)
urls.py
urlpatterns = format_suffix_patterns([
path('', views.api_root),
path('snippets/', views.SnippetList.as_view(), name='snippet-list'),
path('snippets/<int:pk>/', views.SnippetDetail.as_view(), name='snippet-detail'),
path('snippets/<int:pk>/highlight/', views.SnippetHighlight.as_view(), name='snippet-highlight'),
path('users/', views.UserList.as_view(), name='user-list'),
path('users/<int:pk>/', views.UserDetail.as_view(), name='user-detail'),
])
urlpatterns += [
path(r'api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
serializers.py
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html')
class Meta:
model = Snippet
fields = ['url', 'id', 'highlight', 'owner',
'title', 'code', 'linenos', 'language', 'style']
class UserSerializer(serializers.HyperlinkedModelSerializer):
snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail', read_only=True)
class Meta:
model = User
fields = ['url', 'id', 'username', 'snippets']
Traceback error:
Traceback:
File "C:\Anaconda3\envs\python36\lib\site-packages\django\core\handlers\exception.py" in inner 34. response = get_response(request)
File "C:\Anaconda3\envs\python36\lib\site-packages\django\core\handlers\base.py" in _get_response 126. response = self.process_exception_by_middleware(e, request)
File "C:\Anaconda3\envs\python36\lib\site-packages\django\core\handlers\base.py" in _get_response 124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Anaconda3\envs\python36\lib\site-packages\django\views\decorators\csrf.py" in wrapped_view 54. return view_func(*args, **kwargs)
File "C:\Anaconda3\envs\python36\lib\site-packages\django\views\generic\base.py" in view 68. return self.dispatch(request, *args, **kwargs)
File "C:\Anaconda3\envs\python36\lib\site-packages\rest_framework\views.py" in dispatch 505. response = self.handle_exception(exc)
File "C:\Anaconda3\envs\python36\lib\site-packages\rest_framework\views.py" in handle_exception 465. self.raise_uncaught_exception(exc)
File "C:\Anaconda3\envs\python36\lib\site-packages\rest_framework\views.py" in raise_uncaught_exception 476. raise exc
File "C:\Anaconda3\envs\python36\lib\site-packages\rest_framework\views.py" in dispatch 502. response = handler(request, *args, **kwargs)
File "C:\Anaconda3\envs\python36\lib\site-packages\rest_framework\decorators.py" in handler 50. return func(*args, **kwargs)
File "C:\Users\Ze Ran Lu\Desktop\swie\text\tutorials\snippets\views.py" in api_root 205. 'users': reverse('user-list'),
File "C:\Anaconda3\envs\python36\lib\site-packages\rest_framework\reverse.py" in reverse 47. url = _reverse(viewname, args, kwargs, request, format, **extra)
File "C:\Anaconda3\envs\python36\lib\site-packages\rest_framework\reverse.py" in _reverse 60. url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
File "C:\Anaconda3\envs\python36\lib\site-packages\django\urls\base.py" in reverse 90. return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "C:\Anaconda3\envs\python36\lib\site-packages\django\urls\resolvers.py" in _reverse_with_prefix 622. raise NoReverseMatch(msg)
Exception Type: NoReverseMatch at / Exception Value: Reverse for 'user-list' not found. 'user-list' is not a valid view function or pattern name.
Another url.py file is
from django.contrib import admin
from django.urls import path
from django.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('snippets.urls'))
]
Project structure
tutorials
|_snippets
| |_urls.py
| |_views.py
| |_models.py
| |_apps.py
| |_admin.py
|_tutorials
|_urls.py
|_settings.py
|_wsgi.py
reverse only accept these parameter:
reverse(viewname, urlconf=None, args=None, kwargs=None,
current_app=None)
and your users/ doesn't accept any arguments so you only need the url name in reverse
reverse('user-list')

Unable to search using elasticsearch in django with django-elasticsearch-dsl-drf (Set fielddata=true on [title.raw])

I have followed the quick start guide shown here, in order to experiment with elasticsearch searching and a sample Django app I am playing with.
Using elasticsearch 6.3.1 and latest django-elasticsearch-dsl-drf
The results is the following error.
RequestError at /search/movies/
RequestError(400, 'search_phase_execution_exception', 'Fielddata is disabled on text fields by default. Set fielddata=true on [title.raw] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.')
I have added in the django project an extra app named search_indexes.
Here is the documents.py from this app.
# Name of the Elasticsearch index
INDEX = Index('search_movies')
# See Elasticsearch Indices API reference for available settings
INDEX.settings(
number_of_shards=1,
number_of_replicas=1
)
html_strip = analyzer(
'html_strip',
tokenizer="standard",
filter=["standard", "lowercase", "stop", "snowball"],
char_filter=["html_strip"]
)
#INDEX.doc_type
class MovieDocument(DocType):
"""Movie Elasticsearch document."""
id = fields.IntegerField(attr='id')
title = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.StringField(analyzer='keyword'),
}
)
summary = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.StringField(analyzer='keyword'),
}
)
Now, after running manage.py search_index --rebuild, i can visit the url http://localhost:9200/search_movies/_search?pretty where I can see that the index has been created properly and I can see the data as well.
Moving on to the next part this is my serializers.py file
from django_elasticsearch_dsl_drf.serializers import DocumentSerializer
from .documents import MovieDocument
class MovieDocumentSerializer(DocumentSerializer):
"""Serializer for the document."""
class Meta(object):
"""Meta options."""
# Specify the correspondent document class
document = MovieDocument
# List the serializer fields. Note, that the order of the fields
# is preserved in the ViewSet.
fields = (
'id',
'title',
'summary',
'people',
'genres',
)
and then my views.py
from django_elasticsearch_dsl_drf.constants import (
LOOKUP_FILTER_TERMS,
LOOKUP_FILTER_RANGE,
LOOKUP_FILTER_PREFIX,
LOOKUP_FILTER_WILDCARD,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_GT,
LOOKUP_QUERY_GTE,
LOOKUP_QUERY_LT,
LOOKUP_QUERY_LTE,
LOOKUP_QUERY_EXCLUDE,
)
from django_elasticsearch_dsl_drf.filter_backends import (
FilteringFilterBackend,
IdsFilterBackend,
OrderingFilterBackend,
DefaultOrderingFilterBackend,
SearchFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import BaseDocumentViewSet
from django_elasticsearch_dsl_drf.pagination import PageNumberPagination
from .documents import MovieDocument
from .serializers import MovieDocumentSerializer
class MovieDocumentView(BaseDocumentViewSet):
"""The MovieDocument view."""
document = MovieDocument
serializer_class = MovieDocumentSerializer
pagination_class = PageNumberPagination
lookup_field = 'id'
filter_backends = [
FilteringFilterBackend,
IdsFilterBackend,
OrderingFilterBackend,
DefaultOrderingFilterBackend,
SearchFilterBackend,
]
# Define search fields
search_fields = (
'title',
'summary',
)
# Define filter fields
filter_fields = {
'id': {
'field': 'id',
# Note, that we limit the lookups of id field in this example,
# to `range`, `in`, `gt`, `gte`, `lt` and `lte` filters.
'lookups': [
LOOKUP_FILTER_RANGE,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_GT,
LOOKUP_QUERY_GTE,
LOOKUP_QUERY_LT,
LOOKUP_QUERY_LTE,
],
},
'title': 'title.raw',
'genres': {
'field': 'genres',
# Note, that we limit the lookups of `genres` field
# to `terms, `prefix`, `wildcard`, `in` and
# `exclude` filters.
'lookups': [
LOOKUP_FILTER_TERMS,
LOOKUP_FILTER_PREFIX,
LOOKUP_FILTER_WILDCARD,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_EXCLUDE,
],
},
'genres.raw': {
'field': 'genres.raw',
'lookups': [
LOOKUP_FILTER_TERMS,
LOOKUP_FILTER_PREFIX,
LOOKUP_FILTER_WILDCARD,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_EXCLUDE,
],
},
}
# Define ordering fields
ordering_fields = {
'id': 'id',
'title': 'title.raw',
}
# Specify default ordering
ordering = ('id', 'title')
Lastly my urls.py is the following
from django.conf.urls import url, include
from rest_framework import routers
from .views import MovieDocumentView
router = routers.DefaultRouter()
router.register(r'movies', MovieDocumentView, base_name='moviedocument')
urlpatterns = [
url(r'^', include(router.urls)),
]
So, when i visit a url like http://localhost:8000/search/movies/ or http://localhost:8000/search/movies/?summary__contains=photography the error I mentioned above shows up.
Here is the stacktrace
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
/usr/local/lib/python3.7/dist-packages/django_elasticsearch_dsl_drf/filter_backends/search/historical.py:231: UserWarning: SearchFilterBackend is deprecated. Switch to `CompoundSearchFilterBackend`.
self.__class__.__name__
GET http://localhost:9200/search_movies/doc/_search [status:400 request:0.013s]
Internal Server Error: /search/movies/
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/dist-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.7/dist-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.7/dist-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/er/.local/lib/python3.7/site-packages/rest_framework/viewsets.py", line 103, in view
return self.dispatch(request, *args, **kwargs)
File "/home/er/.local/lib/python3.7/site-packages/rest_framework/views.py", line 483, in dispatch
response = self.handle_exception(exc)
File "/home/er/.local/lib/python3.7/site-packages/rest_framework/views.py", line 443, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/er/.local/lib/python3.7/site-packages/rest_framework/views.py", line 480, in dispatch
response = handler(request, *args, **kwargs)
File "/home/er/.local/lib/python3.7/site-packages/rest_framework/mixins.py", line 48, in list
return Response(serializer.data)
File "/home/er/.local/lib/python3.7/site-packages/rest_framework/serializers.py", line 765, in data
ret = super(ListSerializer, self).data
File "/home/er/.local/lib/python3.7/site-packages/rest_framework/serializers.py", line 262, in data
self._data = self.to_representation(self.instance)
File "/home/er/.local/lib/python3.7/site-packages/rest_framework/serializers.py", line 683, in to_representation
self.child.to_representation(item) for item in iterable
File "/home/er/.local/lib/python3.7/site-packages/elasticsearch_dsl/search.py", line 329, in __iter__
return iter(self.execute())
File "/home/er/.local/lib/python3.7/site-packages/elasticsearch_dsl/search.py", line 706, in execute
**self._params
File "/home/er/.local/lib/python3.7/site-packages/elasticsearch/client/utils.py", line 84, in _wrapped
return func(*args, params=params, **kwargs)
File "/home/er/.local/lib/python3.7/site-packages/elasticsearch/client/__init__.py", line 844, in search
"GET", _make_path(index, doc_type, "_search"), params=params, body=body
File "/home/er/.local/lib/python3.7/site-packages/elasticsearch/transport.py", line 353, in perform_request
timeout=timeout,
File "/home/er/.local/lib/python3.7/site-packages/elasticsearch/connection/http_urllib3.py", line 236, in perform_request
self._raise_error(response.status, raw_data)
File "/home/er/.local/lib/python3.7/site-packages/elasticsearch/connection/base.py", line 162, in _raise_error
status_code, error_message, additional_info
elasticsearch.exceptions.RequestError: RequestError(400, 'search_phase_execution_exception', 'Fielddata is disabled on text fields by default. Set fielddata=true on [title.raw] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.')
[07/Aug/2019 11:03:38] "GET /search/movies/?summary__contains=photography HTTP/1.1" 500 154541
What you're supposed to do is to use KeywordField instead of StringField with keyword analyzer:
title = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.KeywordField(), <---- change this
}
)

Manager isn't available; 'auth.User' has been swapped for 'members.CustomUser'

i have problem with my code when i want signup error appear Manager isn't available; 'auth.User' has been swapped for 'members.CustomUser' , i try solotion of other questions same like Manager isn't available; 'auth.User' has been swapped for 'members.CustomUser' but all of them asking to replace User = User = get_user_model() but i am not use any User in my code or i dont know where i used that.im new in django , python , js and etc so if my question is silly forgivme .
for more information :1) i used Django Signup Tutorial for create signup method . first that was working well but after i expand my homework project i get error .2)in others app ("products" and "search") no where im not import User and even i dont use CustomUser too bez not need to work with User in this apps.just memebers work with User and CustomUser.
model.py :
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
def __str__(self):
return self.email
class Meta:
verbose_name = "member"
verbose_name_plural = "members"
setting.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'card.apps.CardConfig',
'members.apps.MembersConfig',
'search.apps.SearchConfig',
'products.apps.ProductsConfig',
'rest_framework',
]
AUTH_USER_MODEL = 'members.CustomUser'
admin.py:
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['email', 'username']
admin.site.register(CustomUser, CustomUserAdmin)
form.py:
# users/forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = ('username', 'email')
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('username', 'email')
error:
27/Feb/2019 12:36:01] "GET /signup/ HTTP/1.1" 200 5293
Internal Server Error: /signup/
Traceback (most recent call last):
File "C:\shopping\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\shopping\venv\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\shopping\venv\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\shopping\venv\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\shopping\venv\lib\site-packages\django\views\generic\base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "C:\shopping\venv\lib\site-packages\django\views\generic\edit.py", line 172, in post
return super().post(request, *args, **kwargs)
File "C:\shopping\venv\lib\site-packages\django\views\generic\edit.py", line 141, in post
if form.is_valid():
File "C:\shopping\venv\lib\site-packages\django\forms\forms.py", line 185, in is_valid
return self.is_bound and not self.errors
File "C:\shopping\venv\lib\site-packages\django\forms\forms.py", line 180, in errors
self.full_clean()
File "C:\shopping\venv\lib\site-packages\django\forms\forms.py", line 383, in full_clean
self._post_clean()
File "C:\shopping\venv\lib\site-packages\django\contrib\auth\forms.py", line 107, in _post_clean
super()._post_clean()
File "C:\shopping\venv\lib\site-packages\django\forms\models.py", line 403, in _post_clean
self.instance.full_clean(exclude=exclude, validate_unique=False)
File "C:\shopping\venv\lib\site-packages\django\db\models\base.py", line 1137, in full_clean
self.clean()
File "C:\shopping\venv\lib\site-packages\django\contrib\auth\models.py", line 338, in clean
self.email = self.__class__.objects.normalize_email(self.email)
File "C:\shopping\venv\lib\site-packages\django\db\models\manager.py", line 188, in __get__
cls._meta.swapped,
AttributeError: Manager isn't available; 'auth.User' has been swapped for 'members.CustomUser'
[27/Feb/2019 12:36:04] "POST /signup/ HTTP/1.1" 500 113770
Modify views.py
from django.contrib.auth.forms import UserCreationForm
from django.urls import reverse_lazy
from django.views import generic
class SignUp(generic.CreateView):
form_class = UserCreationForm
success_url = reverse_lazy('login')
template_name = 'signup.html'
to
from .forms import CustomUserCreationForm
from django.urls import reverse_lazy
from django.views import generic
class SignUp(generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'signup.html'
In your forms.py make changes as:
from django.contrib.auth import get_user_model
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
fields = ('username', 'email')
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = ('username', 'email')
Also add this script in your members/init.py file:
default_app_config = 'members.apps.MembersConfig'

Django 1.9.2 test Client issue

I'm using Django==1.9.2 and djangorestframework==3.3.2, and django.test.Client to make some tests. The problem is that when I execute my tests I'm gettting this error:
ERROR: test_view (main.tests.test_http.TestMainViewSet)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/vladir/work/all/project-django1.9/saxo-publish/publish/main/tests/test_http.py", line 111, in test_view
content_type='application/json'
File "/home/vladir/work/all/project-django1.9/venv/local/lib/python2.7/site-packages/django/test/client.py", line 515, in post
secure=secure, **extra)
File "/home/vladir/work/all/project-django1.9/venv/local/lib/python2.7/site-packages/django/test/client.py", line 314, in post
secure=secure, **extra)
File "/home/vladir/work/all/project-django1.9/venv/local/lib/python2.7/site-packages/django/test/client.py", line 380, in generic
return self.request(**r)
File "/home/vladir/work/all/project-django1.9/venv/local/lib/python2.7/site-packages/django/test/client.py", line 449, in request
response = self.handler(environ)
File "/home/vladir/work/all/project-django1.9/venv/local/lib/python2.7/site-packages/django/test/client.py", line 123, in __call__
response = self.get_response(request)
File "/home/vladir/work/all/project-django1.9/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 245, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "/home/vladir/work/all/project-django1.9/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 296, in handle_uncaught_exception
return callback(request, **param_dict)
File "/home/vladir/work/all/project-django1.9/venv/local/lib/python2.7/site-packages/django/utils/decorators.py", line 166, in _wrapped_view
return middleware.process_response(request, response)
File "/home/vladir/work/all/project-django1.9/venv/local/lib/python2.7/site-packages/django/middleware/csrf.py", line 230, in process_response
request.META["CSRF_COOKIE"],
KeyError: u'CSRF_COOKIE'
My test code looks like this:
import json
from django.test import Client
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
class TestMainViewSet(TestCase):
def setUp(self):
self.client = Client(
HTTP_HOST='example.com' # I have also tried removing this
)
self.create_read_url = reverse('books-list')
User.objects.create_user(
username="username",
email="username#zunzun.se",
password="123"
)
def test_create(self):
self.client.login(username='username', password="123")
# In this case I'm doing a POST, but it is the same with a GET
response = self.client.post(
self.create_read_url,
data=json.dumps({'title': "Create"}), # I have also tried without the json.dumps
content_type='application/json'
)
data = json.loads(response.content)
print data
self.assertEqual(response.status_code, 201)
self.assertEquals(data['title'], "Create")
my view code is:
from django.contrib.auth.mixins import LoginRequiredMixin
from rest_framework import viewsets
from .serialiazers import (
BookSerializerRead,
BookSerializerWrite,
)
class MainViewSet(LoginRequiredMixin, viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class_read = BookSerializerRead
serializer_class_write = BookSerializerWrite
on the urls.py:
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'books', MainViewSet, 'books')
urlpatterns = [
url(r'^api/', include(router.urls)),
]
According with the Django doc about it, I should not need anything additional to avoid the CSRF checks,
because as textually said there: "By default, the test client will disable any CSRF checks performed by your site.", and I also know that enforce_csrf_checks=False by default
on the Client.
I have found one detail though, if I create an instance of the client that way self.client = Client(HTTP_HOST='example.com', CSRF_COOKIE='xxxxxx') then it works, but is that
actually needed? It is not what the documentation says, so I suppose I'm doing something wrong. Could someone help me with that please? I will appreciate any help about.
Thanks in advance
Try to use DRF's APITestCase as base class for test cases:
from rest_framework.testing import APITestCase
class TestMainViewSet(APITestCase):
...