2015-04-08 17 views
6

Tôi đang làm việc trên một dự án sử dụng django-rest-framework. Trong chế độ xem API của tôi, người dùng được xác thực có thể tạo người dùng khác. Nhưng, chỉ có năm. Sau đó, nếu có năm người dùng đã đăng ký bởi một người dùng, tôi muốn gửi cho anh ấy phản hồi đã đạt đến giới hạn. Sau đó, tôi cần phải nhận được trên serializer của tôi người sử dụng xác thực nhưng, tôi không thể tìm thấy một cách để vượt qua nó từ ModelViewSet của tôi để serializer của tôi.Làm thế nào để có được xác thực người dùng trên lớp serializer để xác nhận

Đây là mã của tôi:

Xem:

class ChildUserViewSet(viewsets.ModelViewSet): 
    serializer_class = ChildUserSerializer 
    queryset = User.objects.all() 

    authentication_classes = (
     TokenAuthentication, 
    ) 
    permission_classes = (
     IsAuthenticated, 
    ) 

    def perform_create(self, serializer): 
     account_group = self.request.user.userprofile.get_account_group 

     mobile_number = serializer.data.get('mobile_number') 
     password = serializer.data.get('password') 
     user = serializer.save() 
     user.set_password(password) 
     user.save() 

     # Generate user profile 
     UserProfile.objects.create(
      user=user, 
      mobile_number=mobile_number, 
      user_type=CHILD, 
      related_account_group=account_group, 
     ) 

Serializer:

class ChildUserSerializer(serializers.ModelSerializer): 
    mobile_number = serializers.CharField() 

    class Meta: 
     model = User 

     fields = (
      'first_name', 
      'last_name', 
      'email', 
      'password', 
      'mobile_number', 
     ) 

    def validate(self, data): 
     """ 
     Check that the start is before the stop. 
     """ 
     # Get authenticated user for raise hit limit validation 



    def validate_email(self, value): 
     if User.objects.filter(email=value): 
      raise serializers.ValidationError("This field must be unique.") 
     return value 

    def create(self, validated_data): 
     username = generate_unique_username(
      u'{0}{1}'.format(
       validated_data['first_name'], 
       validated_data['last_name'], 
      ) 
     ) 

     user = User(
      username=username, 
      first_name=validated_data['first_name'], 
      last_name=validated_data['last_name'], 
      email=validated_data['email'], 
     ) 

     user.set_password(validated_data['password']) 
     user.save() 

     return user 

Sau đó, trong def validate(self, data) chức năng của serializer của tôi, tôi muốn để có được những người dùng hiện chứng thực.

Làm cách nào để chuyển request.user từ APIView sang bộ nối tiếp của tôi?

Trả lời

8

Tôi đã tìm thấy một cách dễ dàng hơn để hoàn thành việc này! Nó chỉ ra rằng lớp GenericAPIView cơ sở nghỉ ngơi Khung của (mà từ đó tất cả các View lớp generic Nghỉ ngơi Khung của xuống) includes a function called get_serializer_context():

def get_serializer_context(self): 
    """ 
    Extra context provided to the serializer class. 
    """ 
    return { 
     'request': self.request, 
     'format': self.format_kwarg, 
     'view': self 
    } 

Như bạn có thể thấy, trở context đối tượng chứa cùng đối tượng request rằng Xem nhận được. Đối tượng này sau đó được thiết lập when the serializer is initialized:

def get_serializer(self, *args, **kwargs): 
    """ 
    Return the serializer instance that should be used for validating and 
    deserializing input, and for serializing output. 
    """ 
    serializer_class = self.get_serializer_class() 
    kwargs['context'] = self.get_serializer_context() 
    return serializer_class(*args, **kwargs) 

Như vậy để truy cập người dùng thực hiện yêu cầu, bạn chỉ cần gọi self.context['request'].user từ bên trong validate_ chức năng của Serializer của bạn:

class TemplateSerializer(serializers.ModelSerializer): 
    def validate_parent(self, value): 
     print(self.context['request'].user) 

     return value 

    class Meta: 
     model = Template 

Và phần tốt nhất là bạn không phải ghi đè bất kỳ thứ gì trong số ModelViewSet của mình, chúng có thể đơn giản như bạn muốn chúng:

class TemplateViewSet(viewsets.ModelViewSet): 
    serializer_class = TemplateSerializer 
    permission_classes = [IsAdmin] 
3

Bạn có thể chuyển ngữ cảnh bổ sung cho bộ nối tiếp của mình với serializer = ChildUserSerializer(data, context={'request': request}). Sau đó, bạn có thể truy cập vào người dùng được xác thực qua request.user trong phương thức xác thực trình tuần tự của bạn.

1

Trong quan điểm của bạn khi bạn khởi serializer như

serializer = ChildUserSerializer(data=request.DATA,context={'request':request})

, gửi một bối cảnh mà chứa request.Then trong serializers bên trong chức năng gọi

request=self.context['request']

Sau đó, bạn có thể truy cập request.user.

2

Trong djangorestframework> 3.2.4 lớp rest_framework.generic.GenericAPIView bao gồm yêu cầu http theo mặc định trong bối cảnh serializer.

Vì vậy, bên serializer của bạn, bạn có thể truy cập nó bằng cách: self.context['request'] và người dùng self.context['request'].user

Vì vậy ChildUserSerializer của bạn sẽ trông giống như:

class ChildUserSerializer(serializers.ModelSerializer): 
    mobile_number = serializers.CharField() 
    .... 
    def validate(self, data): 
     """ 
     Check that the start is before the stop. 
     """ 
     # Get authenticated user for raise hit limit validation 
     user = self.context['request'].user 
     # do something with the user here 
    def validate_email(self, value): 
     if User.objects.filter(email=value): 
      raise serializers.ValidationError("This field must be unique.") 
     return value 
    ... 
Các vấn đề liên quan