我正在尝试使可编辑数据表与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"}
]
},
]
});
});
答案 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"))