一个错找半天,搜也没搜着结果,最终自己找到了才感觉很难绷。所以特别记下来找错的过程。
1 症状
《python 从入门到实践》19章。一直有个topic.html进不去,报这个错。
初步理解啊,这个错应该是说有行代码调用一个对象时没找着。
先重新尝试python manage.py runserver,把服务器重开了,防止又是因为服务器宕机导致半天进不去网址。结果还是没进去。然后看了看其它网址,topics.html能进,log in和log out没问题,new_topic.html也能进...总之就是目前做的项目里的所有html都试了试,就topic.html不能进,一直是这个错。
2 找错过程
报错也证实,就是topic.html的问题,显示问题在这一行。看起来,它没找着topic.id这个变量。
对了对书,这行代码没错啊。为了确定是不是topic.html就这行代码错了,把这行删了(注意不能注释,必须删掉)再尝试打开网页,可以能打开,说明在topic.html中,就这行有问题,但是问题不在这行代码上,而是在它调用的代码上。我初学不会啊,不知道它调用的谁啊,只能很笨拙地在view.py中的各个函数里逐个添加print(1),然后对照着运行着服务器的cmd看结果。当我在view.py的def topic里写print(1)时,发现cmd有反应了,给了个1,因此上面这个报错行调用的就是def topic。
现在附上我纠正错误之前的def topic代码:
@login_required
def topic(request, topic_id):
"""显示所有的主题"""
topic = get_object_or_404(Topic, id=topic_id)
# 确认请求的主题属于当前用户
if topic.owner != request.user:
raise Http404
entries = topic.entry_set.order_by('-date_added')
context = {'topic:': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context)
乍看之下,一点问题没有啊,该传的topic我传了啊。我还担心它传的topic.id是字符,导致那边认不出来,还print(type(topic.id))一下,出来个int,没错啊。结果仔细一看,context的topic多了个冒号(不知道您刚才发现没有),删掉就对了。一个手误,整了两天没找着。我多添加的这个冒号,意味着传给context的变量是‘topic:’而不是‘topic’,也就解释了为什么topic.html找不到topic.id了。
3 事后总结
但是这找错,也是有所收获的。一番搜索和比较下,我比较认可这个网址说的,面对django的NoReverseMatch问题的应对方法:https://fedingo.com/how-to-fix-noreversematch-error-in-django/#:~:text=What%20is%20NoReverseMatch%20Error%20in%20Django%20When%20you,matches%20your%20specified%20url_name%2C%20it%20returns%20NoReverseMatch%20Error.
用我这回错的案例概括一下,就是:
- 先看html里有没有写对。这指的就是我的topic.html,您可以看看您错的是哪个html。重点关注对象的名字、语法有没有没错,比如{% %}的百分号和大括号之间是不是有空格这种。
- 检查管这个html的urls.py有没有写对。这里指的就是learning_logs\urls.py,看看管topic.html的那一行代码,name是不是对的。
- 检查管上面这个urls.py的再上一级urls.py有没有写对。这里指的就是learning_log\urls.py,看看有没有把上面那个urls.py正确地加到这个urls.py的urlpatterns里。其实如果像我这样,删掉html报问题的一行,网页就能打开,其它页面也没问题的话,基本上2.和3.都没啥问题。
- 检查报错这个参数的类型对不对。上文,我报错的那一行就用了topic.id这个参数,我用print(type(topic.id))检查了这个id的类型,就排除了这个问题。
- 检查报错行调用的函数。要是不知道报错行调用的谁,我上边介绍过了怎么找。然后重点看这个函数传的context有没有问题,看清楚传的啥、传给render没有。细心一点,别像我这样。