我正在扩展django auth表的用户模型,并为此实现rest api。
我没有得到如何实现相同的GET / POST请求。
我的models.py代码是:
class UserProfile(models.Model):
"""User profile model for information about user."""
users = models.OneToOneField(User)
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'")
phone_number = models.CharField(max_length=100, validators=[phone_regex], blank=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):
"""Serializer for users."""
class Meta:
model = User
class UserProfileSerializer(serializers.ModelSerializer):
"""Serializer for user profiles."""
users = UserSerializer(many=True)
class Meta:
model = UserProfile
def create(self, validated_data):
users_data = validated_data.pop('users')
print 'yes'
print users_data
user_profile = UserProfile.objects.create(**validated_data)
for user_data in users_data:
user_data, created = User.objects.get_or_create(first_name=user_data['first_name'], last_name=user_data['last_name'],
username=user_data['username'], password=user_data['password'], email=user_data['email'], is_active=['is_active'])
user_profile.users.add(user_data)
return user_profile
我的v1.py代码是:
class UserProfileList(APIView):
"""Get and post user profiles data."""
def get(self, request, format=None):
"""Get users."""
user_profiles = UserProfile.objects.all()
serialized_user_profiles = UserProfileSerializer(user_profiles, many=True)
return Response(serialized_user_profiles.data)
def post(self, request, format=None):
"""Post users."""
serializer = UserSerializer(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)
我认为问题出在v1.py文件中。我想发出GET和POST请求,对于POST请求我想发送JSON数据。有人可以帮助我实现它。实际上,我想要单个端点来发出POST请求并在User模型和UserProfile模型中存储数据。
答案 0 :(得分:1)
修改上述代码
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)
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
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()
请点击此链接routers
from rest_framework import routers
router = routers.SimpleRouter()
router.register('users', MyUserViewSet)
from .routers import router
urlpatterns = patterns(
url(r'^api/v1/', include(router.urls)),
)
答案 1 :(得分:0)
我建议你通过继承AbstractBaseUser扩展User模型,它还需要继承BaseUserManager。这样,您就可以通过只有一个类来简化序列化程序。它还需要BaseUserManager的子类化。
自定义用户可以拥有任意数量的自定义字段。以这种方式扩展用户模型通常比创建与默认用户模型的一对一关系更简单。它为您节省了一些逻辑和时间。
您可以在这里阅读更多内容: https://docs.djangoproject.com/ja/1.9/topics/auth/customizing/#specifying-a-custom-user-model
以下是如何进行子类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
这是一个子类化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
为此,您需要在settings.py中设置auth用户模型,让django应用知道您使用的是自定义用户模型:
AUTH_USER_MODEL = 'myapp.MyUser'
这是一个简单的部分 - 序列化器:
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
当你在这里时,忘掉APIView并使用更简单的ViewSet:
class MyUserViewSet(viewsets.ModelViewSet):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (AllowAny, )
serializer_class = MyUserSerializer
仅凭这一点,您就可以处理GET,POST,PUT,DELETE请求。