如何使用django restfulframework 实现文件上传

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用django restfulframework 实现文件上传相关的知识,希望对你有一定的参考价值。

参考技术A 当服务端的server程序收到客户端的连接后,就创建子进程,并且将子进程的标准输入、标准输出、标准错误重定向到已连接的套接字,然后execl执行pyth.py,这样客户端client和pyth.py程序的交互就相当于在本机控制台上交互是一样的了。
编写客户端程序tcpclient.c如下:
l tcpClient.c

点击(此处)折叠或打开
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <memory.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 9999
#define Buflen 1024
int main(int argc,char *argv[])

struct sockaddr_in server_addr;
int n,err;
int sockfd;
char recvline[Buflen];本回答被提问者采纳

如何仅使用 django 作为后端并使用 django-rest-framework 发布

【中文标题】如何仅使用 django 作为后端并使用 django-rest-framework 发布【英文标题】:How to use django only a backend and post with django-rest-framework 【发布时间】:2016-11-27 12:06:00 【问题描述】:

我将只使用 Django 作为后端。前端将使用 React 完成,没有 django 模板。我正在使用django-rest-framework 为我的网站创建一个rest api。

我为用户做了一个序列化器。

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) vagrant@precise32:~$ http --json POST http://55.55.55.5/custom/users/ email="ter23minal2@gmail.com" password="terminal2123" username="t223erm" first_name="te2er" last_name="mi2nal" date_of_birth=1992-12-12 gender=2 mobile_number=66222666666336

它创建并返回新的用户对象。

所以我制作了一个表格来注册一个我没有从 django 服务器提供服务的用户:

<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>

和 ajax 发布表单。

// 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);
        
    );
);

现在如果我点击按钮,问题就开始了:

即使我给了event.preventDefault(),页面也会自动加载到django服务器的url(即http://55.55.55.5/custom/users/)。 我收到一个错误:“详细信息”:“CSRF 失败:CSRF 令牌丢失或不正确。”

如何使用 django-rest-framework 处理到 django 服务器的帖子?我没有找到解决这个问题的任何帮助材料。你能指导我怎么做吗?谢谢。

【问题讨论】:

你能澄清谁在为前端页面提供服务吗?是服务器直接渲染的静态 HTML/JS,还是 Django 渲染的?假设它是一个静态文件,那么我不确定使用 CSRF 是否有意义,因为您可能应该使用令牌或类似的安全性。 @dkarchmer 是的,它是由 nodejs 渲染的静态 HTML/JS。如果我还不是用户,如何使用令牌?我认为如果用户进行身份验证,就会给出令牌。你能指导我吗?谢谢。 【参考方案1】:

您可以使用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 看到完整的工作示例(免责声明,这是我的代码)。

希望对你有帮助

【讨论】:

以上是关于如何使用django restfulframework 实现文件上传的主要内容,如果未能解决你的问题,请参考以下文章

如何使用django session

Django:当我使用 django 表单时,如何实现这个 html 表单

django-1-新手如何使用django

如何仅使用 django 作为后端并使用 django-rest-framework 发布

如何使用WSGI部署Django

如何使用 Django 配置 Celery 守护进程