2016-06-01 4 views
0

django auth 테이블의 User 모델을 확장하고 나머지 API를 구현했습니다.Django Rest 프레임 워크에서 중첩 시리얼 라이저를 구현하는 방법은 무엇입니까?

동일한 방법으로 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 요청을하고 사용자 모델과 UserProfile 모델 모두에 데이터를 저장하기위한 단일 종단점이 필요합니다.

답변

1

위의 코드를

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 수정.평

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

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

'URL (R '^ V1/사용자/$ ', csrf_exempt (userregistration.v1.MyUserViewSet.as_view ({'get ':'queryset '}))),'urls.py 파일에서'QuerySet '객체를 호출 할 수 없습니다. – Ankit

+0

get 매개 변수에'queryset'을 매핑하면 mapp { "get": "list"}가 필요합니다. 이 링크를 따라 http://www.django-rest-framework.org/api-guide/routers/#example –

+0

시도했지만 오류가 발생했습니다 'MyUserViewSet'객체에 'list'속성이 없습니다 – Ankit

0

BaseUserManager를 서브 클래 싱해야하는 AbstractBaseUser를 서브 클래 싱하여 사용자 모델을 확장하는 것이 좋습니다. 그렇게하면 직렬화 프로그램을 하나의 클래스로만 단순화 할 수 있습니다. 또한 BaseUserManager의 서브 클래 싱이 필요합니다.

사용자 지정 사용자는 원하는만큼 많은 사용자 지정 필드를 가질 수 있습니다. 일반적으로 기본 사용자 모델과 일대일 관계를 만드는 것보다 사용자 모델을이 방법으로 확장하는 것이 더 간단합니다. 그것은 당신에게 약간의 논리와 시간을 절약 해줍니다.

당신은 더 많은 읽을 수 있습니다 여기에 : 여기 https://docs.djangoproject.com/ja/1.9/topics/auth/customizing/#specifying-a-custom-user-model

당신이 하위 클래스 BaseUserManager 할 것입니다 방법의 예 :이를 위해

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 

: 여기

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의 예 작동하려면 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 잊고 사용하는 훨씬 간단 뷰셋 :

class MyUserViewSet(viewsets.ModelViewSet): 
    authentication_classes = (TokenAuthentication, SessionAuthentication) 
    permission_classes = (AllowAny,) 
    serializer_class = MyUserSerializer 

그리고 이것만으로도 GET, POST, PUT, DELETE 요청을 처리 할 수 ​​있습니다.

관련 문제