Django添加addbook函数后遇ValueError:Field 'id'期望数字却获'add'
解决Django中访问/book/add时出现ValueError的问题
问题现象
原本正常展示图书列表的网站,添加addbook视图函数后,访问/book/add时出现错误:
ValueError at /book/add Field 'id' expected a number but got 'add'.
相关代码
all_book.html
{% extends 'base.html' %} {% block content %} <h1>kljgf</h1> <a href ="{% url 'addbook' %}">Add Book</a> {% for book in books %} <h3> <a href = "{% url 'detail_book' book.id %}">{{book.namebook}}</a> </h3> <hr> {% endfor %} {% endblock content %}
views.py
def detail_book(request, id): boo = book.objects.get(id=id) context = {'book' : boo} return render(request, 'detail_book.html', context) def addbook(request): book_form = book_form() context = {'form' : book_form} return render(request, 'add_book.html', context)
urls.py
path('book/<id>', views.detail_book, name="detail_book"), path('book/add', views.addbook, name="addbook"),
add_book.html
{% extends 'base.html' %} {% block content %} <h1>add book </h1> <form method="POST"> {% csrf_token %} {{form}} </form> {% endblock content %}
问题原因
Django的URL路由匹配是从上到下按顺序匹配的。当前urls.py中,path('book/<id>', ...)在path('book/add', ...)前面,当访问/book/add时,Django会把add当作<id>参数的值传递给detail_book视图函数。而detail_book中执行book.objects.get(id=id)查询时,id接收的是字符串'add'而非数字,因此抛出ValueError。
解决方案
1. 调整路由顺序
把book/add的路由放在book/<id>的前面,让Django优先匹配明确的路径:
path('book/add', views.addbook, name="addbook"), path('book/<id>', views.detail_book, name="detail_book"),
2. 给id参数指定类型(推荐)
给<id>指定int类型,这样Django会自动校验参数必须是整数,从根源上避免非数字参数传入:
path('book/add', views.addbook, name="addbook"), path('book/<int:id>', views.detail_book, name="detail_book"),
修改完成后,访问/book/add会正确匹配到addbook视图,数字id的路径会匹配到detail_book视图,同时<int:id>能过滤掉非数字的无效参数,避免不必要的错误。
内容的提问来源于stack exchange,提问作者dadi game
相关产品推荐
相关产品推荐

