Archived
Member class now extends User (new in Django 1.5). Fixed all other files to work with this change.
This commit is contained in:
1 parent
48ae4107c5
commit
eb45d7aa00
4 files changed
+539
-605
No files matched your search
+11
-69
@@ -13,18 +13,13 @@ class MemberResource(ModelResource):
|
||||
(1) /api/v1/member/
|
||||
(2) /api/v1/member/{id}/
|
||||
"""
|
||||
username = fields.CharField(attribute='username', readonly=True)
|
||||
email = fields.CharField(attribute='email', readonly=True)
|
||||
first_name = fields.CharField(attribute='first_name', readonly=True)
|
||||
last_name = fields.CharField(attribute='last_name', readonly=True)
|
||||
|
||||
class Meta:
|
||||
queryset = Member.objects.all()
|
||||
resource_name = 'member'
|
||||
list_allowed_methods = [ 'get', 'post' ]
|
||||
detail_allowed_methods = [ 'get', 'patch' ]
|
||||
authorization = Authorization() # TODO: for dev (VERY INSECURE)
|
||||
excludes = [ 'password' ]
|
||||
excludes = [ 'date_joined', 'password', 'is_active', 'is_staff', 'is_superuser', 'last_login' ]
|
||||
filtering = {
|
||||
'username' : [ 'exact' ],
|
||||
'email' : [ 'exact' ],
|
||||
@@ -33,15 +28,6 @@ class MemberResource(ModelResource):
|
||||
'phone_number' : [ 'exact' ],
|
||||
}
|
||||
|
||||
def build_filters(self, filters=None):
|
||||
# This is actually vanilla implementation and currently redundant, but I didn't
|
||||
# delete it in case we're going to use it for something.
|
||||
if filters is None:
|
||||
filters = {}
|
||||
|
||||
orm_filters = super(MemberResource, self).build_filters(filters)
|
||||
return orm_filters
|
||||
|
||||
def apply_filters(self, request, applicable_filters):
|
||||
# Extra filters are used for filtering by attributes in User class. Find out if there
|
||||
# are any, and if so, apply them.
|
||||
@@ -60,66 +46,22 @@ class MemberResource(ModelResource):
|
||||
filtered = super(MemberResource, self).apply_filters(request, applicable_filters)
|
||||
|
||||
for key,value in extra_filters.items():
|
||||
filtered = filter(lambda m: getattr(m.user, key) == value, filtered)
|
||||
filtered = filter(lambda m: getattr(m, key) == value, filtered)
|
||||
|
||||
return filtered
|
||||
|
||||
def hydrate(self, bundle):
|
||||
"""
|
||||
Catches POST and PATCH requests and intercepts data that are supposed to go into
|
||||
User class and not in Member.
|
||||
Catches POST and PATCH requests and intercepts data.
|
||||
"""
|
||||
|
||||
# Fields that are in the User class and not in Member:
|
||||
possible_fields = [ 'username', 'password', 'email', 'first_name', 'last_name' ]
|
||||
|
||||
# From above possibilities, contains fields that are actually in the request:
|
||||
user_params = {}
|
||||
|
||||
for field in possible_fields:
|
||||
if field in bundle.data:
|
||||
data = bundle.data.pop(field)
|
||||
user_params[field] = data
|
||||
|
||||
# Check if we also need to create User when creating Member:
|
||||
if bundle.obj.user_id == None: # true if new user
|
||||
user = User(**user_params)
|
||||
user.save()
|
||||
self.member_created(**user_params)
|
||||
bundle.data['user_id'] = user.id
|
||||
bundle.obj.user_id = user.id
|
||||
if bundle.obj.user_ptr_id == None: # True if new user
|
||||
pass
|
||||
else:
|
||||
# This happens only if we're editing existing user.
|
||||
new_password = None # Needed later if we're changing password.
|
||||
for key, value in user_params.items():
|
||||
if key == 'password':
|
||||
# Password has to be hashed before it can be set:
|
||||
bundle.obj.user.set_password(value)
|
||||
new_password = value
|
||||
elif key == 'username':
|
||||
if value != bundle.obj.user.username:
|
||||
for key, value in bundle.data.items():
|
||||
if key == 'username':
|
||||
if value != bundle.obj.username:
|
||||
# We can't change username.
|
||||
raise ImmediateHttpResponse(HttpForbidden("You can't change your username."))
|
||||
else:
|
||||
# For all other fields, just change the damn field:
|
||||
setattr(bundle.obj.user, key, value)
|
||||
# hydrate is normally NOT used for updating Model objects, so we have to save it manually:
|
||||
bundle.obj.user.save()
|
||||
if new_password is not None:
|
||||
self.member_password_changed(bundle.obj.user.username, new_password)
|
||||
return bundle
|
||||
|
||||
def dehydrate(self, bundle):
|
||||
return bundle
|
||||
|
||||
def member_created(self, **kwargs):
|
||||
"""
|
||||
TODO: This function is called every time new user is created.
|
||||
"""
|
||||
pass
|
||||
|
||||
def member_password_changed(self, username, new_password):
|
||||
"""
|
||||
TODO: This function is called every time user changes his password.
|
||||
"""
|
||||
pass
|
||||
elif key == 'password':
|
||||
bundle.obj.set_password(value)
|
||||
return bundle
|
||||
+516
-512
File diff suppressed because it is too large.
Load diff
+1
-10
@@ -25,16 +25,7 @@ class PlaceOfStudy(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
updated = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Member(models.Model):
|
||||
# Auth:
|
||||
user = models.OneToOneField(django.contrib.auth.models.User)
|
||||
|
||||
def username(self): return self.user.username
|
||||
def email(self): return self.user.email
|
||||
def first_name(self): return self.user.first_name
|
||||
def last_name(self): return self.user.last_name
|
||||
|
||||
# Profile fields:
|
||||
class Member(django.contrib.auth.models.User):
|
||||
phone_number = models.IntegerField(unique=True, null=True, blank=True)
|
||||
date_of_birth = models.DateField(blank=True, null=True)
|
||||
legacy_id = models.IntegerField(unique=True, null=True, blank=True)
|
||||
|
||||
+11
-14
@@ -1,6 +1,5 @@
|
||||
import logging
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from support.test import ResourceTestCase
|
||||
from main.models import Member
|
||||
|
||||
@@ -34,8 +33,7 @@ class MemberTest(ResourceTestCase):
|
||||
|
||||
# Get the preloaded member, which will be used for
|
||||
# comparison with fetched object.
|
||||
self.member = User.objects.get(username=self.standard_username)
|
||||
self.member_profile = self.member.get_profile()
|
||||
self.member = Member.objects.get(username=self.standard_username)
|
||||
|
||||
# URI to get the existing member. We'll probably
|
||||
# need it at one point or another.
|
||||
@@ -92,7 +90,7 @@ class MemberTest(ResourceTestCase):
|
||||
data = {
|
||||
"username" : self.member.username,
|
||||
"email" : self.member.email,
|
||||
"phone_number" : self.member_profile.phone_number
|
||||
"phone_number" : self.member.phone_number
|
||||
}
|
||||
|
||||
for key, value in data.items():
|
||||
@@ -124,14 +122,13 @@ class MemberTest(ResourceTestCase):
|
||||
|
||||
# Check if user was actually put into database:
|
||||
try:
|
||||
user = User.objects.get(username=data['username'])
|
||||
except User.DoesNotExist:
|
||||
user = Member.objects.get(username=data['username'])
|
||||
except Member.DoesNotExist:
|
||||
self.fail("Inserted user does not exist.")
|
||||
self.assertNotEquals(None, user)
|
||||
self.assertEquals(user.email, data['email'])
|
||||
|
||||
user_profile = user.get_profile()
|
||||
self.assertEquals(user_profile.phone_number, data['phone_number'])
|
||||
self.assertEquals(user.phone_number, data['phone_number'])
|
||||
|
||||
def test_patch_change_member(self):
|
||||
"""
|
||||
@@ -149,10 +146,10 @@ class MemberTest(ResourceTestCase):
|
||||
self.assertHttpAccepted(resp)
|
||||
|
||||
# Check if user was actually updated:
|
||||
user = User.objects.get(username=self.standard_username)
|
||||
user = Member.objects.get(username=self.standard_username)
|
||||
self.assertNotEquals(user.password, data['password']) # just to ensure that it's encrypted
|
||||
self.assertEquals(user.email, data['email'])
|
||||
self.assertEquals(user.get_profile().phone_number, data['phone_number'])
|
||||
self.assertEquals(user.phone_number, data['phone_number'])
|
||||
|
||||
def test_patch_invalid_change_member(self):
|
||||
"""
|
||||
@@ -166,13 +163,13 @@ class MemberTest(ResourceTestCase):
|
||||
self.assertHttpForbidden(resp)
|
||||
|
||||
try:
|
||||
User.objects.get(username=oldusername)
|
||||
except User.DoesNotExist:
|
||||
Member.objects.get(username=oldusername)
|
||||
except Member.DoesNotExist:
|
||||
self.fail("Username was changed. It is not supposed to.")
|
||||
|
||||
try:
|
||||
User.objects.get(username=newusername)
|
||||
Member.objects.get(username=newusername)
|
||||
self.fail("You will never see this message. If you do, call +7 331 24 337 for further instructions.")
|
||||
except User.DoesNotExist:
|
||||
except Member.DoesNotExist:
|
||||
pass # ...the test.
|
||||
|
||||
Reference in new issue
Block a user