I'm making RESTful API using Tastypie, and when I try to POST/PUT/DELETE a request it says:
"detail": "CSRF Failed: CSRF token missing or incorrect.".
It works fine with GET. I've read various threads on SO, saying:
to delete the cookies
or use #csrf_exempt
or use #method_decorator(csrf_exempt)
but neither of it worked.
How can I over-pass this error?
views.py
class SnippetList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
request._dont_enforce_csrf_checks = True
print request.DATA
return self.create(request, *args, **kwargs)
serializer.py
from django.forms import widgets
from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
urls.py
from django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
urlpatterns = patterns('',
url(r'^snippets/$', views.SnippetList.as_view()),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
)
urlpatterns = format_suffix_patterns(urlpatterns)
Change rest_framework default permissions to AllowAny in settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
...
}
Related
I am trying to use Django Rest Framework and face a problem. The problem is when i try to use DjangoModelPermissions it doesn't follow the permission from Django admin panel.
What I excepted, is that when I set permission Projects|projects|can view projects then user can see the output.
Here are my codes:
Views.py
from rest_framework import viewsets
from rest_framework.permissions import IsAdminUser, IsAuthenticated, DjangoModelPermissions
from django.shortcuts import get_object_or_404
from rest_framework.response import Response
from .models import Projects
from .serializers import ProjectSerializer
class ProjectsViewSet(viewsets.ViewSet):
permission_classes_by_action = {'list': [DjangoModelPermissions]}
queryset = Projects.objects.none()
serializer_class = ProjectSerializer
def list(self, request):
queryset = Projects.objects.all()
serializer = ProjectSerializer(queryset, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
queryset = Projects.objects.all()
project = get_object_or_404(queryset, pk=pk)
serializer = ProjectSerializer(project)
return Response(serializer.data)
def get_permissions(self):
try:
return [permission() for permission in self.permission_classes_by_action[self]]
except KeyError:
return [permission() for permission in self.permission_classes]
serializers.py
from rest_framework import serializers
from .models import Projects
class ProjectSerializer(serializers.ModelSerializer):
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
class Meta:
model = Projects
fields = ('id','name')
Django admin site permission for the user: []
Output
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 1,
"name": "proj 1"
},
{
"id": 2,
"name": "proj 222"
}
]
I don't know if it would help but, I am using custom User AUTH_USER_MODEL="users.Users"
Thanks in advance
Thank you for your time.
I was working on django rest framework documentation, and only with Localhost "http://127.0.0.1:8000/" URL I get this error.
TypeError at /
can only concatenate str (not "builtin_function_or_method") to str
I have attached Views.py, snippets/url.py and snippets/serializers.py
views.py
from snippets.permissions import IsOwnerOrReadOnly
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer, UserSerializer
from rest_framework import generics, permissions
from django.contrib.auth.models import User
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import renderers
from rest_framework.reverse import reverse
#api_view(['GET']
def api_root(request, fromat=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
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.RetrieveUpdateDestroyAPIView):
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
snippets/urls.py
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
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')
])
serializer.py
from rest_framework import serializer
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
from django.contrib.auth.models import User
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.ModelSerializer):
snippets = serializers.HyperlinkedIdentityField(many=True, view_name='snippet-detail',
read_only=True)
class Meta:
model = User
fields = ['url', 'id', 'username', 'snippets']
irrespective of this everything's working perfectly, like http://127.0.0.1:8000/snippets/
I have a generic APIView where I'm overriding the create method. This is for the Group model, where I've added a password field:
views.py
from django.contrib.auth.hashers import check_password, make_password
from django.contrib.auth.models import Group
from django.http import Http404
from rest_framework import generics
from rest_framework import status
from rest_framework.response import Response
from .permissions import AllowOptionsAuthentication
from .serializers import GroupSerializer
class GroupList(generics.ListCreateAPIView):
queryset = Group.objects.all()
serializer_class = GroupSerializer
permission_classes = [AllowOptionsAuthentication]
def create(self, request, *args, **kwargs):
data = request.data
data['password'] = make_password(data['password'])
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
print(Group.objects.get(name=data['d']).__dict__) # shows hashed password
print(serializer.data) # shows hashed password
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class GroupDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Group.objects.all()
serializer_class = GroupSerializer
permission_classes = [AllowOptionsAuthentication]
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
try:
# Grabs the 'name' parameter from the URL
group = queryset.get(name=self.kwargs['name'])
except Group.DoesNotExist:
raise Http404
if not check_password(self.request.data['password'], group.password):
raise Http404
group.user_set.add(self.request.user)
self.check_object_permissions(self.request, group)
return group
serializers.py
class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
fields = ('id', 'name', 'password')
models.py
from django.contrib.auth.models import Group
from django.db.models import CharField, Model
Group.add_to_class('password', CharField(max_length=180, null=True, blank=True))
urls.py
from django.urls import path
from .views import GroupList, GroupDetail
urlpatterns = [
path('groups/', GroupList.as_view()),
path('groups/<str:name>/', GroupDetail.as_view()),
]
permissions.py
from rest_framework.permissions import IsAuthenticated
class AllowOptionsAuthentication(IsAuthenticated):
def has_permission(self, request, view):
if request.method == 'OPTIONS':
return True
return super(IsAuthenticated, self).has_permission(request, view)
settings.py
INSTALLED_APPS = [
'rest_framework',
'rest_framework.authtoken',
'djoser',
'corsheaders',
# ...
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
}
Inexplicably, after checking both the serializer.data and querying the database directly in the above print statements, I confirm that I have passed a hashed password into the column. However, whenever I query this afterwards, I see that the raw password has been saved.
I cannot explain how the password is becoming unhashed after saving the hashed password to the database. I am not writing to the Group model anywhere else.
But when I query this model after leaving the create method:
print(Group.objects.get(name='TestGroup').__dict__) # shows raw password
I need to upload an image to django server with django rest framework. I tried to post the image using httpie and I am getting this error.
http 400 no image was submitted.
serializers.py
from rest_framework import serializers
from myapp.models import *
class PhotoSerializer(serializers.ModelSerializer):
image = serializers.ImageField(max_length=None,use_url=True)
class Meta:
model = MyPhoto
fields = ('id', 'image')
models.py
from django.db import models
class MyPhoto(models.Model):
image = models.ImageField(upload_to='photos/', max_length=254)
views.py
from rest_framework.views import APIView
from myapp.models import *
from myapp.serializers import PhotoSerializer
from rest_framework import status
from rest_framework.response import Response
from rest_framework.parsers import FormParser, MultiPartParser
class PhotoList(APIView):
parser_classes = (FormParser, MultiPartParser)
def get(self, request, format=None):
photo = MyPhoto.objects.all()
serializer = PhotoSerializer(photo, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
def post(self, request, format=None):
serializer = PhotoSerializer(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)
I have setMEDIA_ROOT and MEDIA_URL.
Try this way. this might help you to resolve your issue.
views.py
from rest_framework.viewsets import ModelViewSet
from myapp.models import *
from myapp.serializers import PhotoSerializer
class PhotoList(ModelViewSet):
serializer_class = PhotoSerializer
queryset = MyPhoto.objects.all()
urls.py
from django.conf.urls import include, url
from rest_framework.routers import DefaultRouter
from myapp.views import PhotoList
router = DefaultRouter()
router.register(r'photo', PhotoList, 'photo')
urlpatterns = [
url(r'^', include(router.urls)),
]
Just use url in browser http://localhost:8000/photo/.
iam new to django and i started a blog app. after a while when i want to login
into the admin 0.0.0.1:8000/admin I get an error
DoesNotExist at /admin/login/
Site matching query does not exist.
I have no idea why. Maybe it has something to do, that I installed django-registration-redux or with my urlpatterns in main and in the blog app.
Maybe somebody can give me advice also about better urlpatterns?
My main aim is to do a create view with login required mixin. This doesnt work too when i put the loginrequiredmixin in the class blog_postCreateView.
I appreciate every help. Iam new (noob). Looking forward for your answer.
IF there is anything what i can improve just tell me , thanks
Thanks a lot
main url
from django.conf.urls import url, include
from django.contrib import admin
from blog.views import AboutPageView, ContactPageView, blog_postCreateView
urlpatterns = [
url(r'', include('blog.urls')),
url(r'^blog/', include('blog.urls')),
url(r'^about/$', AboutPageView.as_view(), name='about'),
url(r'^contact/$', ContactPageView.as_view(), name='contact'),
url(r'^create/$', blog_postCreateView.as_view(), name='blog_post_create'),
#admin and login
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('registration.backends.default.urls')),
]
blog urls
from django.conf.urls import url
from .views import blog_postListView, blog_postDetailView, blog_postCreateView
urlpatterns = [
url(r'^$', blog_postListView.as_view(), name='blog_post_list'),
url(r'^(?P<slug>[-\w]+)$', blog_postDetailView.as_view(), name='blog_post_detail'),
]
views
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.http import HttpResponse
from django.views.generic import View
from django.views.generic.base import TemplateView, TemplateResponseMixin, ContextMixin
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.shortcuts import render
from django.utils.decorators import method_decorator
from .models import blog_post
from .forms import blog_postForm
# Create your views here.
class LoginRequiredMixin(object):
#classmethod
def as_view(cls, **kwargs):
view = super(LoginRequiredMixin, cls).as_view(**kwargs)
return login_required(view)
##method_decorator(login_required)
#def dispatch(self, request, *args, **kwargs):
# return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
class blog_postCreateView(CreateView):
#model = blog_post
form_class = blog_postForm
template_name = "form.html"
#fields = ["title", "content"]
def get_success_url(self):
return reverse("blog_post_list")
# #method_decorator(login_required)
# def dispatch(self, request, *args, **kwargs):
# return super(MyView, self).dispatch(request, *args, **kwargs)
class blog_postListView(ListView):
model = blog_post
def get_queryset(self, *args, **kwargs):
qs = super(blog_postListView, self).get_queryset(*args, **kwargs).order_by("-timestamp")
return qs
class blog_postDetailView(DetailView):
model = blog_post
class AboutPageView(TemplateView):
template_name = "about.html"
class ContactPageView(TemplateView):
template_name = "contact.html"
models
from __future__ import unicode_literals
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models.signals import pre_save, post_save
from django.utils.text import slugify
# Create your models here.
class blog_post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
content = models.TextField()
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __unicode__(self):
return self.title
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("blog_post_detail", kwargs={"slug": self.slug})
def create_slug(instance, new_slug=None):
slug = slugify(instance.title)
if new_slug is not None:
slug = new_slug
qs = blog_post.objects.filter(slug=slug).order_by("-id")
exists = qs.exists()
if exists:
new_slug = "%s-%s" %(slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug
def pre_save_post_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = create_slug(instance)
pre_save.connect(pre_save_post_receiver, sender=blog_post)
forms
from django import forms
from .models import blog_post
class blog_postForm(forms.ModelForm):
class Meta:
model = blog_post
fields = [
'title',
'content',
]