2016-07-23 4 views
3

장고를 백엔드로만 사용합니다. 프론트 엔드는 React와 django 템플릿을 사용하지 않고 끝납니다. 내 웹 사이트의 나머지 API를 만들려면 django-rest-framework을 사용하고 있습니다.django 만 백엔드로 사용하고 django-rest-framework로 게시하는 방법

사용자를 위해 시리얼 라이저를 만들었습니다.

class CustomUserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = CustomUser 
     fields = (
      'id', 'email', 'password', 'username', 'first_name', 'last_name', 'date_of_birth', 'gender', 'mobile_number' 
     ) 
     extra_kwargs = { 
      'password': {'write_only': True}, 
      'id': {'read_only': True} 
     } 

    def create(self, validated_data): 
     user = CustomUser.objects.create(
      email=validated_data['email'], 
      username=validated_data['email'], 
      first_name=validated_data['first_name'], 
      last_name=validated_data['last_name'], 
      date_of_birth=validated_data['date_of_birth'], 
      gender=validated_data['gender'], 
      mobile_number=validated_data['mobile_number'] 
     ) 
     user.set_password(validated_data['password']) 
     user.save() 
     return user 

class CustomUserViewSet(viewsets.ModelViewSet): 
    queryset = CustomUser.objects.all() 
    serializer_class = CustomUserSerializer 

브라우저에서/custom/users /로 이동하면 사용자를 볼 수 있습니다. 성공적인 등록 후에 사용자를 다시 돌려주는 새로운 사용자를 만들 수도 있습니다. 또한 httpie/curl을 사용하면 작동합니다.

(djangoweb) [email protected]:~$ http --json POST http://55.55.55.5/custom/users/ email="[email protected]" password="terminal2123" username="t223erm" first_name="te2er" last_name="mi2nal" date_of_birth=1992-12-12 gender=2 mobile_number=66222666666336 

새 사용자 개체를 만들어 반환합니다.

<form action="http://55.55.55.5/custom/users/" method="post" id="register-form"> 
    <input type="text" placeholder="email" name="email"/> 
    ... 
    ... 
    <button id="post">Register</button> 
</form> 

그리고 아약스 양식을 게시 할 수 :

그래서 내가 장고 서버에서 제공하고 있지 않다 사용자를 등록 양식을했다. 내가 버튼을 클릭하면

// using the javscript Cookies library 
var csrftoken = Cookies.get('csrftoken'); 

function csrfSafeMethod(method) { 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
} 
$.ajaxSetup({ 
    beforeSend: function(xhr, settings) { 
     if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
      xhr.setRequestHeader("X-CSRFToken", csrftoken); 
     } 
    } 
}); 

$('#post').click(function(event) { 
    event.preventDefault(); 
    var $form = $('#register-form'); 
    var data = $form.serialize();   
    $.ajax({ 
     type: "POST", 
     url: "http://55.55.55.5/custom/users/", 
     data: JSON.stringify(data), 
     sucess: function() { console.log("Success!"); }, 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     crossDomain:false, 
     beforeSend: function(xhr, settings) { 
      xhr.setRequestHeader("X-CSRFToken", csrftoken); 
     } 
    }); 
}); 

지금 후, 문제가 시작 : 나는 페이지가 자동으로 장고 서버의 URL로로드 event.preventDefault()을했다하더라도

어떻게 django-rest-framework를 사용하여 django 서버에 대한 게시물을 처리 할 수 ​​있습니까? 이 문제에 도움이되는 자료를 찾지 못했습니다. 어떻게 안내해 줄 수 있니? 고맙습니다.

+0

프런트 엔드 페이지를 제공하는 사용자를 분명히 할 수 있습니까? 정적 HTML/JS 직접 서버에 의해 렌더링됩니다, 또는 장고 그것을 렌더링 무엇입니까? 정적 파일이라고 가정하면, 보안을 위해 토큰 등을 사용하고있을 가능성이 있으므로 CSRF를 사용하는 것이 합리적이지는 않습니다. – dkarchmer

+0

@dkarchmer 예, nodejs에서 렌더링 한 정적 HTML/JS입니다. 내가 아직 사용자가 아닌 경우 어떻게 토큰을 사용할 수 있습니까? 나는 사용자가 인증하면 토큰이 주어 졌다고 생각했다. 제발 날 안내해 주시겠습니까? 고맙습니다. – Robin

답변

3

csrf_exempt을 등록 및 로그인 기능으로 사용할 수 있습니다. 예를 들어 등록 및 로그인 API를 만드는 방법은 다음과 같습니다. 내 로그인 API가 토큰을 반환하는 방법을 확인하십시오. http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication을 참조하십시오.

모델 이름을 바꾸기 위해 코드를 편집하려고했지만 테스트하지 않았으므로 내가 가지고있는 오타를 수정해야합니다 (또는 해결할 수 있도록 알려주세요).

class AccountViewSet(viewsets.ModelViewSet): 
    queryset = CustomUser.objects.all() 
    serializer_class = CustomUserSerializer 

    def get_permissions(self): 

     if self.request.method in permissions.SAFE_METHODS: 
      return (permissions.IsAuthenticated(),) 

     if self.request.method == 'POST': 
      return (permissions.AllowAny(),) 

     return (permissions.IsAuthenticated(), IsAccountOwner(),) 

    @csrf_exempt 
    def create(self, request): 
     ''' 
     When you create an object using the serializer\'s .save() method, the 
     object\'s attributes are set literally. This means that a user registering with 
     the password \'password\' will have their password stored as \'password\'. This is bad 
     for a couple of reasons: 1) Storing passwords in plain text is a massive security 
     issue. 2) Django hashes and salts passwords before comparing them, so the user 
     wouldn\'t be able to log in using \'password\' as their password. 

     We solve this problem by overriding the .create() method for this viewset and 
     using Account.objects.create_user() to create the Account object. 
     ''' 

     serializer = self.serializer_class(data=request.data) 

     if serializer.is_valid(): 
      password = serializer.validated_data['password'] 
      confirm_password = serializer.validated_data['confirm_password'] 

      if password and confirm_password and password == confirm_password: 

       user = CustomUser.objects.create_user(**serializer.validated_data) 

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

       return Response(serializer.validated_data, status=status.HTTP_201_CREATED) 

     return Response({'status': 'Bad request', 
         'message': 'Account could not be created with received data.' 
         }, status=status.HTTP_400_BAD_REQUEST) 

class APILoginViewSet(APIView): 

    @csrf_exempt 
    def post(self, request, format=None): 
     data = JSONParser().parse(request) 
     serializer = LoginCustomSerializer(data=data) 

     if serializer.is_valid(): 
      email = serializer.data.get('email') 
      password = serializer.data.get('password') 

      if not request.user.is_anonymous(): 
       return Response('Already Logged-in', status=status.HTTP_403_FORBIDDEN) 

      user = authenticate(email=email, password=password) 

      if user is not None: 
       if user.is_active: 
        login(request, account) 

        serialized = UserSerializer(user) 
        data = serialized.data 

        # Add the token to the return serialization 
        try: 
         token = Token.objects.get(user=user) 
        except: 
         token = Token.objects.create(user=user) 

        data['token'] = token.key 

        return Response(data) 
       else: 
        return Response('This account is not Active.', status=status.HTTP_401_UNAUTHORIZED) 
      else: 
       return Response('Username/password combination invalid.', status=status.HTTP_401_UNAUTHORIZED) 

     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

    def get(self, request, format=None): 
     data_dic = {"Error":"GET not supported for this command"} 
     return Response(data_dic, status=status.HTTP_400_BAD_REQUEST) 

https://github.com/dkarchmer/django-aws-template (면책 조항, 내 코드)에서 전체 작동 예제를 볼 수 있습니다.

희망입니다.