Django导航POST输入实现动态视图:城市选择会话存储咨询
解决方案:Django中通过导航选择保存城市到会话并作为视图输入
核心结论
不需要用POST方式,城市选择属于查询类操作,用GET更符合HTTP语义(无副作用、可收藏、可刷新),完全可以实现将选中城市存入会话的需求。
分步实现
1. 改造导航栏模板(base.html)
把硬编码的城市改成动态从模型读取,同时给每个城市链接添加指向处理视图的URL,并高亮当前选中的城市:
<div class="navigation"> <ul> {% for city in cities %} <li> <a href="{% url 'set_city' city.slug %}" class="{% if request.session.selected_city_slug == city.slug %}active{% endif %}"> <span class="title">{{ city.name }}</span> </a> </li> {% endfor %} </ul> </div>
- 用
{% url %}模板标签生成正确的路由,避免硬编码URL - 通过
request.session判断当前选中城市,添加active类实现高亮 - 从视图传入
cities变量,动态渲染所有城市
2. 编写城市选择处理视图
创建一个视图,负责将用户选中的城市存入会话,然后重定向到房产数据页面:
from django.shortcuts import redirect, get_object_or_404 from django.views.decorators.http import require_GET from .models import City @require_GET # 限定只能用GET请求 def set_city(request, city_slug): # 获取选中的城市对象,不存在则返回404 city = get_object_or_404(City, slug=city_slug) # 将城市的slug存入会话(也可以存ID,slug更友好) request.session['selected_city_slug'] = city.slug # 重定向到房产数据展示页面 return redirect('property_list')
3. 改造房产数据展示视图
从会话中读取选中的城市,作为查询条件筛选房产数据:
from django.shortcuts import render, get_object_or_404 from .models import City, Property def property_list(request): # 从会话获取选中的城市slug,无值则用默认城市 selected_slug = request.session.get('selected_city_slug') if selected_slug: city = get_object_or_404(City, slug=selected_slug) properties = Property.objects.filter(city=city) else: # 首次访问时,默认展示第一个城市的数据 first_city = City.objects.first() if first_city: properties = Property.objects.filter(city=first_city) request.session['selected_city_slug'] = first_city.slug city = first_city else: properties = Property.objects.none() city = None context = { 'properties': properties, 'selected_city': city, 'cities': City.objects.all() # 传给导航栏的城市列表 } return render(request, 'property_list.html', context)
4. 配置URL路由
在urls.py中添加对应的路由规则:
from django.urls import path from . import views urlpatterns = [ path('properties/', views.property_list, name='property_list'), path('set-city/<slug:city_slug>/', views.set_city, name='set_city'), ]
关键说明
- 为什么不用POST?:POST用于提交修改数据的操作(如创建、更新),而城市选择是查询资源的行为,用GET更符合REST规范,且用户可以收藏链接、刷新页面不会触发重复提交。
- 会话的可靠性:Django默认开启会话支持,数据会存在数据库或缓存中,只要用户浏览器开启Cookie就能正常工作。
内容的提问来源于stack exchange,提问作者Bruno_BNF
相关产品推荐
相关产品推荐

