我正在尝试创建一个简单的Todo网站,允许您记录待办事项并将其标记为已完成。我遇到的问题是网址。
当你第一次去localholst:8000 / todo /一切都很好,它显示了我所有的待办事项。我现在希望能够选中一个旁边的复选框,并让列表自动更新,并将该待办事项划掉。当你从localhost执行此操作时:8000 / todo /它工作正常但是你留在localhost:8000 / todos / check / 3 url(这个url允许我通过regexp url捕获这个视图单击该todo项目更新数据库。)
问题:如果我再点击另一个待办事项项目将其标记为已完成,则无效。如果我尝试点击id = 4的待办事项,我的URL是localhost:8000 / todos / check / 3 / check / 4。你可以看到,在我做了一次后,它使用url来捕获更新数据库的视图,但是它应该已经将用户发送回localhost:8000 / todo /来设置下一次检查。相反,它将我们留在localhost:8000 / todos / check / 3并添加到" / check / 4"到最后。
问题:我怎么能失去"检查/ 3"在我处理了对数据库的实际更新之后从url?
我的主要urls.py(指向我的todo / urls.py文件):
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^todo/', include("todo.urls", namespace="todo")),
)
我的todo / urls.py文件:
from django.conf.urls import patterns, url
from todo import views
urlpatterns = patterns('',
url(r'^add/$', views.add, name='add'),
url(r'^remove/$', views.remove_done, name='remove'),
url(r'^check/(?P<todo_id>\d+)/$', views.check, name='check'),
url(r'^$', views.index, name='index'),
)
views.py(截断)
from todo.models import todo
def index(request):
todos_done = todo.objects.filter(done = True) # @UndefinedVariable
todos_not_done = todo.objects.filter(done = False)
total_todos = todos_done.count() + todos_not_done.count()
return render(request, 'todo/index.html', { 'todos_done': todos_done, 'todos_not_done': todos_not_done, 'total': total_todos })
def check(request, todo_id):
todo_to_mark = todo.objects.get(id=todo_id) # @UndefinedVariable
if todo_to_mark.done == True:
todo_to_mark.done = False
else:
todo_to_mark.done = True
todo_to_mark.save()
todos_done = todo.objects.filter(done = True)
todos_not_done = todo.objects.filter(done = False)
total_todos = todos_done.count() + todos_not_done.count()
return render(request, 'todo/index.html', { 'todos_done': todos_done, 'todos_not_done': todos_not_done, 'total': total_todos })
最后,我的templates / todo / index.html文件(截断)
<div>
<span>{{ todos_done|length }} of {{ total }} remaining</span>
[ <a href="{% url 'todo:remove' %}">Clear all done</a> ]
<ul class="unstyled">
{% for todo in todos_done %}
<li>
<input type="checkbox" name="todo{{todo.id}}" id="{{todo.id}}" onchange="todoChecked({{todo.id}})" checked>
<span class="done-true">{{ todo.todo_text }}</span>
</li>
{% endfor %}
{% for todo in todos_not_done %}
<li>
<input type="checkbox" name="todo{{todo.id}}" id="{{todo.id}}" onchange="todoChecked({{todo.id}})" >
<span>{{ todo.todo_text }}</span>
</li>
{% endfor %}
</ul>
<form action="{% url 'todo:add' %}" method="post">
{% csrf_token %}
<input type="text" size="30" name="new_text" id="new_text" placeholder="Add new todo here">
<input class="btn-primary" type="submit" value="Add">
</form>
<!-- Javascript function -->
<script>
function todoChecked(todo_id) {
window.open("../todo/check/" + todo_id);
}
</script>
</div>
答案 0 :(得分:1)
我认为你只是一次击键。尝试使用点,而不是冒号:
<a href="{% url 'todo.remove' %}">Clear all done</a>
答案 1 :(得分:1)
您应该重定向到此列表,而不是在check()
视图中呈现待办事项列表:
from django.shortcuts import get_object_or_404, render
def check(request, todo_id):
todo_to_mark = get_object_or_404(todo, id=todo_id) # @UndefinedVariable
todo_to_mark.done = not todo_to_mark.done
todo_to_mark.save()
return redirect('todo:index')
另外,我建议使用get_object_or_404()
快捷方式获取todo
对象。