Skip to content

Instantly share code, notes, and snippets.

@theskumar
Last active January 16, 2020 01:24
Show Gist options
  • Save theskumar/7022218 to your computer and use it in GitHub Desktop.
Save theskumar/7022218 to your computer and use it in GitHub Desktop.
User Management in django 1.5 and tastypie
import json
from tastypie.exceptions import TastypieError
from tastypie.http import HttpBadRequest
class CustomBadRequest(TastypieError):
"""
This exception is used to interrupt the flow of processing to immediately
return a custom HttpResponse.
Required after upgrading to django-tastypie==0.9.14
"""
def __init__(self, code="", message=""):
self._response = {
"error": {"code": code or "not_provided",
"message": message or "No error message was provided."}}
@property
def response(self):
return HttpBadRequest(
json.dumps(self._response),
content_type='application/json')
tastpie userfrom django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext as _
class User(AbstractUser):
phone_number = models.CharField(_("Phone number"), max_length=20, blank=True)
@property
def name(self):
return self.get_full_name()
def __unicode__(self):
return self.username
class Meta:
verbose_name = _('User')
verbose_name_plural = _('Users')
#==============================================================================
# SIGNALS
#==============================================================================
def signals_import():
""" A note on signals.
The signals need to be imported early on so that they get registered
by the application. Putting the signals here makes sure of this since
the models package gets imported on the application startup.
Important note: added it as a function in case someone does a ctrl+shift+O
in eclipse, the import will not be moved to the top of this file.
"""
from tastypie.models import create_api_key
models.signals.post_save.connect(create_api_key, sender=User)
signals_import()
from django.contrib.auth.hashers import make_password
from tastypie import fields
from tastypie.authentication import (Authentication, BasicAuthentication,
MultiAuthentication, ApiKeyAuthentication)
from tastypie.authorization import Authorization
from tastypie.cache import NoCache
from tastypie.resources import ModelResource
from .models import User
from .exceptions import CustomBadRequest
class UserResource(ModelResource):
"""Get and update user profile."""
class Meta:
# Disable caching of objects returned from GET
cache = NoCache()
# For authentication, allow both basic and api key so that the key
# can be grabbed, if needed.
authentication = MultiAuthentication(BasicAuthentication(),
ApiKeyAuthentication() )
authorization = Authorization()
detail_allowed_methods = ['get', 'patch', 'put']
list_allowed_methods = ['patch', 'put']
always_return_data = True
queryset = User.objects.all().select_related("api_key")
fields = ['email', 'first_name', 'last_name', 'phone_number', 'username']
resource_name = 'profile'
def dehydrate(self, bundle):
bundle.data['key'] = bundle.obj.api_key.key
return bundle
def authorized_read_list(self, object_list, bundle):
# Return the profile of user making api reqeust.
return object_list.filter(id=bundle.request.user.id).select_related()
class SignupResource(ModelResource):
"""Endpoint to create a new account for a user."""
class Meta:
queryset = User.objects.all()
detail_allowed_methods = ['post']
list_allowed_methods = []
always_return_data = True
authentication = Authentication()
authorization = Authorization()
resource_name = 'signup'
fields = ['email', 'first_name', 'last_name', 'phone_number', 'username']
def dehydrate(self, bundle):
bundle.data['key'] = bundle.obj.api_key.key
del bundle.data['password']
return bundle
def obj_create(self, bundle, **kwargs):
REQUIRED_USER_FIELDS = ("username", "email", "first_name", "last_name", "raw_password")
for field in REQUIRED_USER_FIELDS:
if field not in bundle.data:
raise CustomBadRequest(
code="missing_key",
message="Must provide {missing_key} when creating a user."
.format(missing_key=field))
try:
username = bundle.data["username"]
if User.objects.filter(username=username):
raise CustomBadRequest(
code="duplicate_exception",
message="That username is already taken.")
except KeyError as missing_key:
raise CustomBadRequest(
code="missing_key",
message="Must provide {missing_key} when creating a user."
.format(missing_key=missing_key))
except User.DoesNotExist:
pass
raw_password = bundle.data.pop('raw_password')
bundle.data["password"] = make_password(raw_password)
return super(SignupResource, self).obj_create(bundle, **kwargs)
@lukaskris
Copy link

can u share about the blog post?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment