python 2.7 - User creation with unique constraint in Django Rest framework -


i researched in google, , have tried in lot of ways still not able right. here requirements:

  1. a 1 one field extending user model, has been achieved , new model called customer.
  2. now, new user 201 response returned not data serialized, date_of_birth coming in json format, want user in json response.
  3. if try add user username exists plays bad. trying try , except doesnt work. want response of 409 conflict sent if username exists. here userserializer.py:

-

from django.contrib.auth.models import user rest_framework import serializers   class userserializer(serializers.hyperlinkedmodelserializer):     new_username = serializers.serializermethodfield()      class meta:         model = user         fields = ('url', 'pk', 'username', 'email', 'is_staff', 'new_username')         extra_kwargs = {             'username': {'validators': []},         }      def get_new_username(self, obj):         return obj.username 

here customer model:

from django.db import models django.contrib.auth.models import user   class customer(models.model):     user = models.onetoonefield(user, related_name="customer", on_delete=models.cascade)     date_of_birth = models.datefield(max_length=8)      def __unicode__(self):         return u'%s' % self.user.username 

here customerserializer class:

from django.contrib.auth.models import user django.contrib.auth import get_user_model  rest_framework import serializers, status rest_framework.response import response  customers.models import customer api.serializers import userserializer   class customerserializer(serializers.hyperlinkedmodelserializer):     user = userserializer()     class meta:         model = customer         fields = ('url', 'date_of_birth', 'user')      def create(self, validated_data):         print "coming inside serializer create"         user_data = validated_data.pop("user")         print user_data         try:             userinstance = user.objects.get_or_create(**user_data)[0]             print "user..."             print userinstance             print validated_data             customer = customer.objects.create(user=userinstance, **validated_data)             print customer.user             return customer         except exception exception:             print exception             # print "customer --> %s " % customer             return customer      def update(self, instance, validated_data):         print "coming inside update"         user_data = validated_data.pop("user")         username = user_data.pop('username')         user = get_user_model().objects.get_or_create(username=username)[0]         user.username = username         user.email = user_data.get('email', user.email)         user.save()          # instance.user = user         instance.date_of_birth = validated_data.get('date_of_birth', instance.date_of_birth)         instance.save() 

and here view set customer:

from rest_framework import viewsets  customers.models import customer customers.serializers import customerserializer api.permissions import isowneroradmin  rest_framework import authentication, permissions, status rest_framework.response import response   class customerviewset(viewsets.modelviewset):     serializer_class = customerserializer     queryset = customer.objects.all()     authentication_classes = (authentication.tokenauthentication,                               authentication.sessionauthentication,                               authentication.sessionauthentication, )      def get_permissions(self):         if self.action == 'list':             self.permission_classes = (permissions.isadminuser,)         elif self.action == 'create':             self.permission_classes = (permissions.allowany,)          return super(self.__class__, self).get_permissions()      def create(self, request, *args, **kwargs):         print "this view create -----------------------------"         serializer = self.get_serializer(data=request.data)         # print serializer          if serializer.is_valid():  # passes because here there no new objects created yet             print "serializer valid ......"             # self.pre_save(serializer.object)             # user_data = serializer.validated_data.get("user")             # print user_data             self.object = serializer.create(serializer.validated_data)  # creates user (triggering signal) instance , when saving userprofile, give integrity error             # self.post_save(self.object, created=true)             # headers = self.get_success_headers(serializer.data)             print 'coming here ....1'             print self.object             return response(serializer.validated_data, status=status.http_201_created)         print 'coming here..'         return response(serializer.errors, status=status.http_400_bad_request) 

so, create new customers data returned response , status 201 , if username exists, 409 or status code define , data drf should not complaint i.e; right says orderdict not contain pk if modify serializer.

thanks


edit 1


here updated serilizer custom exception:

from django.contrib.auth.models import user django.contrib.auth import get_user_model django.db import integrityerror  rest_framework import serializers, status rest_framework.response import response rest_framework.exceptions import apiexception  customers.models import customer api.serializers import userserializer   class customerserializer(serializers.hyperlinkedmodelserializer):     user = userserializer()     class meta:         model = customer         fields = ('url', 'pk', 'date_of_birth', 'user')      def create(self, validated_data):         print "coming inside serializer create"         user_data = validated_data.pop("user")         print user_data         try:             userinstance = user.objects.create_user(**user_data)             print "user..."             print userinstance             print validated_data             customer = customer.objects.create(user=userinstance, **validated_data)             print customer.user             return customer         # except typeerror exception:         #     print exception         #     # print "customer --> %s " % customer         #     raise typeerror(exception)         except integrityerror exception:             raise custom409(exception)        def update(self, instance, validated_data):         print "coming inside update"         user_data = validated_data.pop("user")         username = user_data.pop('username')         user = get_user_model().objects.get_or_create(username=username)[0]         user.username = username         user.email = user_data.get('email', user.email)         user.save()          # instance.user = user         instance.date_of_birth = validated_data.get('date_of_birth', instance.date_of_birth)         instance.save()          return instance  class custom409(apiexception):     status_code = status.http_409_conflict     default_detail = "user there." 

but still :

    traceback (most recent call last):   file "/home/naveen/projects/gratis/customers/tests.py", line 37, in test_if_anyone_could_create_customers     format='json')   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/rest_framework/test.py", line 299, in post     path, data=data, format=format, content_type=content_type, **extra)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/rest_framework/test.py", line 221, in post     return self.generic('post', path, data, content_type, **extra)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/django/test/client.py", line 379, in generic     return self.request(**r)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/rest_framework/test.py", line 288, in request     return super(apiclient, self).request(**kwargs)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/rest_framework/test.py", line 240, in request     request = super(apirequestfactory, self).request(**kwargs)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/django/test/client.py", line 466, in request     six.reraise(*exc_info)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response     response = wrapped_callback(request, *callback_args, **callback_kwargs)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view     return view_func(*args, **kwargs)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/rest_framework/viewsets.py", line 83, in view     return self.dispatch(request, *args, **kwargs)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/rest_framework/views.py", line 477, in dispatch     response = self.handle_exception(exc)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/rest_framework/views.py", line 437, in handle_exception     self.raise_uncaught_exception(exc)   file "/home/naveen/.virtualenvs/gratis/local/lib/python2.7/site-packages/rest_framework/views.py", line 448, in raise_uncaught_exception     raise exc integrityerror: duplicate key value violates unique constraint "auth_user_username_key" detail:  key (username)=(user2) exists. 

and test case follows:

def test_if_anyone_could_create_customers(self):         create_user = self.client.post('/api/customers/',                                        {'user':{'username': 'user2', 'email': 'user2@gmail.com'}, 'date_of_birth':"1982-10-20"},                                        format='json')         print create_user         self.assertequal(create_user.status_code, 201)          create_user = self.client.post('/api/customers/',                                        {'user': {'username': 'user2', 'email': 'user2@gmail.com'},'date_of_birth': "1982-10-20"},                                        format='json')         print create_user         # no duplicates         user = user.objects.all()         print user         self.assertequal(create_user.status_code, 409) 

this because catching exceptions far broadly in create method. in fact should never (regardless of whether use drf or not)

    except exception exception:         print exception         # print "customer --> %s " % customer         return customer 

you should catch specific exceptions need catch. , shouldn't returning customer @ all. in case, examination of modelserializer tells 1 should catch typeerror. raised again caller handler.

    except typeerror exception:         print exception         # print "customer --> %s " % customer         raise typeerror(exception) 

now should want according comments, not try raising custom error.

from rest_framework.exceptions import apiexception django.utils.encoding import force_text

class custom409(apiexception):     status_code = status.http_409_conflict     default_detail = 'a conflict occurred' 

and then

    except intergrityerror ext:         print exception         # print "customer --> %s " % customer         raise custom409(ext) 

Comments

Popular posts from this blog

php - How to display all orders for a single product showing the most recent first? Woocommerce -

asp.net - How to correctly use QUERY_STRING in ISAPI rewrite? -

angularjs - How restrict admin panel using in backend laravel and admin panel on angular? -