Python 不允许使用PUT方法
我正在尝试制作可编辑的数据表,以便与Django REST框架一起使用。我尝试使用PUT方法更改表字段,但我得到: 不允许使用方法(PUT):/api/zaposleni/2/ 方法不允许:/api/zaposleni/2/ 我已经检查过类似的问题。我在URL和请求体中返回密钥,并且PUT方法被修饰,这不会触发我得到的错误。 添加断点似乎表明代码执行甚至没有到达我的视图 查看:Python 不允许使用PUT方法,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在尝试制作可编辑的数据表,以便与Django REST框架一起使用。我尝试使用PUT方法更改表字段,但我得到: 不允许使用方法(PUT):/api/zaposleni/2/ 方法不允许:/api/zaposleni/2/ 我已经检查过类似的问题。我在URL和请求体中返回密钥,并且PUT方法被修饰,这不会触发我得到的错误。 添加断点似乎表明代码执行甚至没有到达我的视图 查看: class ZaposleniDetail(viewsets.ViewSet): @action(detail
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)
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
]
$(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"}
]
},
]
});
});
网址:
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)
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
]
$(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"}
]
},
]
});
});
这是因为查询正在访问另一个视图(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"))
如何运行django服务器?如果您使用的是IIS,那么webdav模块有问题,您必须禁用它
/api/zaposleni/2/put/
您可以使用decorator操作创建新的url路径。您是否在项目的设置文件中的CORS\u ALLOW\u METHODS
中添加了put
方法?它在本地运行,因此不是IIS。Decorator@action在方法@action上已准备就绪(detail=True,methods=['put'])