不允许使用PUT方法

时间:2019-02-08 13:24:04

标签: python django django-rest-framework

我正在尝试使可编辑数据表与Django REST Framework一起使用。我正在尝试使用PUT方法更改表字段,但得到:

  

不允许的方法(PUT):/ api / zaposleni / 2 /

     

不允许的方法:/ api / zaposleni / 2 /

我在stackoverflow上检查了类似的问题。我在URL和请求正文中返回密钥,并且装饰了PUT方法,该方法不应触发我得到的错误。 添加断点似乎表明代码执行甚至无法达到我的观点。

查看:

class ZaposleniDetail(viewsets.ViewSet):
    @action(detail=True, methods=['put'])
    def put(self, request, pk):

        try:
            zaposleni = Zaposleni.objects.get(pk=pk)
        except Zaposleni.DoesNotExist:
            return HttpResponse(status=404)

        if request.method == 'PUT':
            # this is when you make changes with datatables editor. I think there was a reason I used PUT instead of POST
            # but I cant remember why that was right now.
            # change pk to an int
            pk = int(pk)

            # parse request querydict into dict
            # I could not find a better way to do this.
            data = parser.parse(request.body)

            # extract out the nested dict needed for drf post
            # datatables always send it nested in 'data' but you can change that if you want to
            parsed_data = data['data'][pk]

            for key, val in parsed_data.items():
                # this is the ugliest part of the function
                # This looks at every value in the dictionary and if it is an empty string then it skips it.
                # An empty string means there wasn't a change
                # If it has data if will go through the keys until it gets a match and then update that in the database
                # The problem is I don't want it to update everything because if there was no change it will send a blank string
                # and then it could overwrite an existing value in the database with a blank string.
                if key in parsed_data:
                    if val == '':
                        continue
                    else:
                        if key == 'ima_prezime':
                            Zaposleni.objects.filter(pk=pk).update(ima_prezime=val)
                        if key == 'datum':
                            Zaposleni.objects.filter(pk=pk).update(
                                datum=val)
                        if key == 'boolean':
                            Zaposleni.objects.filter(pk=pk).update(boolean=val)

            # After making a change in the database you will need to send the data back to datatables
            # If it doesn't match what datatables sends then it will not refresh the datatable
            # this code formats everything to match what datatables send in the PUT request
            parsed_data['id'] = str(pk)

            serializer = ZaposleniSerializer(
                Zaposleni.objects.filter(pk=pk), many=True)
            data = serializer.data

            # This will nest it back into the 'data' dict
            data_dict = {'data': data}
            json_data = json.dumps(data_dict)

            return HttpResponse(json_data)

URL:

urlpatterns = [
    url(r'^api/zaposleni/$', views.ZaposleniList.as_view(), name='zaposleni-list'),
    url(r'^', views.TemplateView.as_view(template_name="zaposleni.html")),
    # loads the template
    url(r'^api/zaposleni/(?P<pk>[0-9]+)/$', views.ZaposleniDetail, name='zaposleni-detail'),
    # view to get and post changed to the database with datatables editor
]

jquery:

$(document).ready(function () {
    editor = new $.fn.dataTable.Editor({
        ajax: {
            url: 'api/zaposleni/_id_/',
            type: 'PUT',
            headers: {'X-CSRFToken': '{{ csrf_token }}'},
        },
        "table": "#example",
        "idSrc": 'id',
        "fields": [    
            {
                "label": "Ime Prezime",
                "name": "ima_prezime",
            },
            {
                "label": "Datum",
                "name": "datum",
                "type": "date",
            },
            {
                "label": "Boolean",
                "name": "boolean",
                "type": "select",
                options: [
                    {label: "", value: ""},
                    {label: "True", value: "True"},
                    {label: "False", value: "False"}
                ]
            },
        ]
    });
});

1 个答案:

答案 0 :(得分:1)

这是因为查询命中了另一个视图(TemplateView),该视图显然不接受PUT方法。 Django尝试从上到下匹配URL,以及第二个URL正则表达式:

url(r'^', views.TemplateView.as_view(template_name="zaposleni.html"))

/api/zaposleni/2/匹配。这是因为没有$和正则表达式的结尾。

应该是:

url(r'^$', views.TemplateView.as_view(template_name="zaposleni.html"))