简体   繁体   English

如何制作一个采用POST数据的Django-Rest-Framework API?

[英]How to make a Django-Rest-Framework API that takes POST data?

I'm building a Django application with Django-Rest-Framework APIs. 我正在使用Django-Rest-Framework API构建Django应用程序。 I have built an API endpoint as follows. 我已经建立了如下的API端点。 I want to be able to POST data from my browser. 我希望能够从浏览器发布数据。 I want to retrieve an object model from my Database that has the matching primary as given in the URL. 我想从数据库中检索具有URL中给定的主对象的对象模型。 And I want to operate on that retrieved object based on the data posted by the browser. 我想根据浏览器发布的数据对检索到的对象进行操作。 If I could just grab the posted data from with my ViewSet, I would be done. 如果我可以使用ViewSet来获取发布的数据,那就可以了。 But I don't know how to get to execute that viewset's update() function when I do a POST. 但是我不知道在执行POST时如何执行该视图集的update()函数。

From my urls.py file: 从我的urls.py文件中:

router.register(r'replyComment', views.ReplyComment, base_name="replyComment")

From my views.py file: 从我的views.py文件中:

class ReplyComment(viewsets.ViewSet):
    def update(self,request,pk=None):
        try: 
            origComment = Comment.objects.get(pk=pk)
            # Do something here that modifies the state of origComment and saves it.
            return Response(
                json.dumps(True), 
                status=status.HTTP_200_OK,
            )
        except Exception as exception:
            logger.error(exception)
            return Response(status=status.HTTP_400_BAD_REQUEST)

I'm using the Advanced Rest Client (ARC) tool in my Chrome browser. 我在Chrome浏览器中使用Advanced Rest Client(ARC)工具。 When I point the ARC tool to http://127.0.0.1:3001/api/replyComment/2/ using the POST method, I get the error: 当我使用POST方法将ARC工具指向http://127.0.0.1:3001/api/replyComment/2/ ,出现以下错误:

{
    detail: "CSRF Failed: CSRF token missing or incorrect". 
}

See the screenshot here . 此处查看屏幕截图。 It seems like I'm doing something wrong here with my POST. 似乎我的POST在这里做错了。 Can someone please advise how to do this properly? 有人可以建议如何正确执行此操作吗? How can I get around my CSRF issue? 如何解决CSRF问题? I'm a newbie to Django Rest Frameworks. 我是Django Rest Frameworks的新手。 So if you can provide clear details, it would be most appreciated. 因此,如果您可以提供明确的详细信息,将不胜感激。 Please let me know what changes I need to make to ensure my POST works as I intend it to? 请让我知道我需要进行哪些更改以确保POST可以按预期工作? I need a bit more help than simply referring me to the manual. 我需要的不仅仅是帮助我参考手册。 (I tried that but still couldn't make it work) (我尝试过,但仍然无法正常工作)

CSRF Tokens are required in Django to protect against CSRF(Cross Site Request Forgery). 在Django中,CSRF令牌是必需的,以防止CSRF(跨站点请求伪造)。 For methods that writes something (POST, PUT, DELETE etc), you need to include a CSRF token with your request so that Django knows the request came from your own site. 对于写一些东西(POST,PUT,DELETE等)的方法,您需要在请求中包含CSRF令牌,以便Django知道该请求来自您自己的站点。

You can read more about in Django-rest-framework documentation . 您可以在Django-rest-framework文档中了解更多信息。 And as it says in the doc, you can find how to include the CSRF token in the HTTP Header in Django documentation . 就像在文档中说的那样,您可以在Django文档的HTTP标头中找到如何包含CSRF令牌。

Well. 好。 other answers are correct. 其他答案是正确的。 but i guess your problem is that you don't know how to use these answers. 但我想您的问题是您不知道如何使用这些答案。

here is an example. 这是一个例子。 lets say i want to send a field name with jquery ajax function over PUT method(updating name on a model). 可以说我想通过PUT方法使用jQuery ajax函数发送字段name (更新模型上的名称)。

first we should get the csrf-token from cookies server send us. 首先,我们应该从Cookies服务器获取csrf-token并将其发送给我们。 this function from django documentation does the job(getting some value from cookie): django文档中的以下功能可以完成这项工作(从cookie中获取一些价值):

// using jQuery
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

when we send put request, we will send the csrf token in request header : 当发送put请求时,我们将在request标头中发送csrf令牌:

var jqxhr = $.ajax('/rest/gallery/5/', {
                    method: 'PUT',
                    type: 'PUT',
                    beforeSend: function (xhr) {
                         xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
                    },
                    data: {
                        name: 'salam dadash'
                    }
                });
                jqxhr.done(function (result) {
                    console.log(result);
                });

note that in beforeSend i set the X-CSRFToken so csrf-token is sent in request header. 请注意,在beforeSend我设置了X-CSRFToken以便在请求标头中发送csrf-token。

you should change url and data of course. 您当然应该更改urldata

See the Headers field above the payload? 看到有效载荷上方的标头字段?

Try adding this: 尝试添加以下内容:

{"X-CSRFToken": "gZvnzSFeGp7h68WjCzmFky6wMkiJZXDU"}

I viewed the screen shot and squinted trying to read out the CSRF token you have set on your server. 我查看了屏幕快照,并s着眼睛试图读取您在服务器上设置的CSRF令牌。 So it could be wrong, double check it against your settings.py file. 因此,可能是错误的,请根据您的settings.py文件仔细检查。 Bibhas is correct, but this is how you accomplish a POST using ARC in your browser. Bibhas是正确的,但这是您在浏览器中使用ARC完成POST的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM