Hello every one i need to make three apis for Login , registration and logout...can i make three api with these one serializer...?
serializers.py
from django.contrib.auth.models import User
from rest_framework import serializers
from rest_framework.authtoken.models import Token
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'email', 'password']
extra_kwargs = {'password': {'write_only': True, 'required': True}}
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
Token.objects.create(user=user)
return user
views.py
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from .serializers import UserSerializer
# from rest_framework.authentication import TokenAuthentication
# from rest_framework.permissions import IsAuthenticated
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
# authentication_classes = (TokenAuthentication,)
# permission_classes = (IsAuthenticated, )
urls.py
from django.urls import include, path
from rest_framework import routers
from .views import UserViewSet
from rest_framework.authtoken.views import ObtainAuthToken
router = routers.DefaultRouter()
router.register(r'registration', UserViewSet)
urlpatterns = [
path('', include(router.urls)),
path('signIn/', ObtainAuthToken.as_view())
]
Related
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/
urls.py:
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
app_name = 'accounts'
urlpatterns = [
path('login/', auth_views.LoginView.as_view(template_name="accounts/login.html"),name='login'),
path('logout/', auth_views.LogoutView.as_view(), name="logout"),
path('college/', views.CollegeView.as_view(), name="college"),
path('signup/', views.SignUp.as_view(), name="signup"),
]
views.py
from django.contrib.auth import login, logout
from django.urls import reverse_lazy
from django.views.generic import CreateView
from . import forms
from accounts.models import College
# Create your views here.
class CollegeView(CreateView):
form_class = College
fields = ['college']
success_url = reverse_lazy("login")
template_name = "accounts/college.html"
class SignUp(CreateView):
form_class = forms.UserCreateForm
success_url = reverse_lazy("college")
template_name = "accounts/signup.html"
forms.py
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
from django import forms
class UserCreateForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = ("username", "email", "password1", "password2")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["username"].label = "Display name"
self.fields["email"].label = "Email address"
class CollegeForm(forms.Form):
fields = ("college")
If i try to redirect the success url to login or logout then it works but for college it is not working
It seems you're using namespaces for urls.
Try to set success_url according to app_name like this:
success_url = reverse_lazy("accounts:college")
Or remove namespace from the root urls.py file in include method
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/.
my admin page does not show the fields listed in admin.py.
Here is the admin.py
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from customRegistration.models import ExUserProfile
admin.site.unregister(User)
class UserProfileInline(admin.StackedInline):
model = ExUserProfile
class UserProfileAdmin(UserAdmin):
inlines = [ UserProfileInline, ]
list_display = ('username', 'email','dateofBirth')
admin.site.register(User, UserProfileAdmin)
I do not see the username and dateofBirth field on my admin page.
models.py:
from django.db import models
from registration.models import User
from registration.signals import user_registered
class ExUserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
ishuman = models.BooleanField(required=True)
dateofBirth=models.DateField(required=True)
def __unicode__(self):
return self.user
def user_registered_callback(sender, user, request, **kwargs):
profile = ExUserProfile(user = user)
profile.ishuman = bool(request.POST["ishuman"])
profile.dateofBirth=request.POST["dateofBirth"]
print request.POST["dateofBirth"]
profile.save()
user_registered.connect(user_registered_callback)