1👍
Modifying the above code
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
phone_number = models.CharField(max_length=100, validators=[
RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'")
], blank=True, null=True)
created_timestamp = models.DateTimeField(auto_now_add=True, null=True)
updated_timestamp = models.DateTimeField(auto_now=True, null=True)
Serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
class UserProfileSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
class Meta:
model = UserProfile
def create(self, validated_data):
user_data = validated_data.pop('user', None)
user = User.objects.create_user(**user_data)
return UserProfile.objects.create(user=user, **validated_data)
def update(self, instance, validated_data):
user_dict = validated_data.pop('user', None)
if user_dict:
user_obj = instance.user
for key, value in user_dict.iteritems():
setattr(user_obj, key, value)
user_obj.save()
validated_data["user"] = user_obj
for key, value in validated_data.iteritems():
setattr(instance, key, value)
instance.save()
return instance
viewsets.py
from rest_framework import mixins
from rest_framework import viewsets
class MyUserViewSet(mixins.UpdateModelMixin,
mixins.CreateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (AllowAny, )
serializer_class = UserProfileSerializer
queryset = UserProfile.objects.all()
Follow this link routers
routers.py
from rest_framework import routers
router = routers.SimpleRouter()
router.register('users', MyUserViewSet)
urls.py
from .routers import router
urlpatterns = patterns(
url(r'^api/v1/', include(router.urls)),
)
0👍
I would suggest you extend the User model by subclassing AbstractBaseUser, which requires also subclassing BaseUserManager. That way you will be able to simplify your serializer by having only one class for it. It also requires subclassing of the BaseUserManager.
Custom users can have as many custom fields as you want. It is generally simpler to extend the user model this way than creating a one-to-one relation to the default user model. It saves you some logic and some time.
You can read more here:
https://docs.djangoproject.com/ja/1.9/topics/auth/customizing/#specifying-a-custom-user-model
Here’s an example of how you would do subclass BaseUserManager:
class MyUserManager(BaseUserManager):
def create_user(self, email=None, password=None, dateofbirth=None, username=None):
user = self.model(
email=MyUserManager.normalize_email(email),
dateofbirth=dateofbirth,
username=username
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, dateofbirth, email, password):
user = self.create_user(email=email,
password=password,
username=username,
dateofbirth=dateofbirth,
)
user.is_superuser = True
user.save(using=self._db)
return user
Here’s an example of subclassing AbstractBaseUser:
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True
)
dateofbirth = models.CharField(max_length=30, blank=True)
is_active = models.BooleanField(default=True)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
objects = MyUserManager()
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def __unicode__(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
@property
def is_staff(self):
return self.is_superuser
For this to work you will have to set the auth user model in your settings.py, to let your django app know you are using a custom user model:
AUTH_USER_MODEL = 'myapp.MyUser'
Here’s the simple part – the serializer:
class MyUserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=True)
class Meta:
model = MyUser
fields = (
'email',
'password',
'dateofbirth',
'username',
)
def create(self, validated_data):
password = validated_data.pop("password", None)
email = validated_data.pop("email", None)
username = validated_data.pop("username", None)
user = MyUser.objects.create_user(email=email, password=password, username=username, gender=gender, dateofbirth=dateofbirth)
MyUser.objects.filter(id=user.id).update(**validated_data)
return user
While you’re at it, forget about the APIView and use the much simpler ViewSet:
class MyUserViewSet(viewsets.ModelViewSet):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (AllowAny, )
serializer_class = MyUserSerializer
And with this alone you have GET, POST, PUT, DELETE requests all handled.
- How to put default avatar for a user
- Django HTML 'for loop' not displaying any of the objects in a set
- How to pass Date Range Picker start and end value to django view.py
- How to make sure data over UNX Sockets gets sent in order using Twisted Python
- Can't change default many to many widget in django form