Django根据浏览器地理位置渲染视图异常求助
问题:无法根据GPS坐标切换机场列表显示
我想实现:页面加载时,若能获取浏览器GPS坐标,就加载周边机场;获取失败则加载全部机场。但现在页面始终显示全部机场——GET请求加载页面时显示全部机场,页面加载完成后触发带GPS的POST请求,后台确实执行了获取周边机场的逻辑,但页面渲染没更新。
相关代码
urls.py
urlpatterns = [ path('admin/', admin.site.urls), path('',views.home_view), ]
views.py
def home_view(request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') if request.method == 'POST': Latitude = float(request.POST.get('latitude')) Longitude = float(request.POST.get('longitude')) context = aviationweatherapi.getStationInfo(Latitude,Longitude) print ("Get airports list around current GPS location") else: #The request is GET context = aviationweatherapi.getStationInfo(None, None) print ("Get all airports") context.update({'IP':ip}) return render(request,'acceuil.html',context)
template_Base.html(acceuil.html的基模板)
<body> {% csrf_token %} {% block contenu %} {% endblock %} <script src="https://code.jquery.com/jquery-3.6.0.js"></script> <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script> <script> const findLoc = () => { const success = (position) => { const latitude = position.coords.latitude; const longitude = position.coords.longitude; var data = {'latitude': latitude, 'longitude': longitude }; data.csrfmiddlewaretoken = $('input[name=csrfmiddlewaretoken]').val(); console.log('Location is on'); console.log(data); document.getElementById("LocationLat").innerHTML = latitude; document.getElementById("LocationLon").innerHTML = longitude; $.post("/", data); } const error = () => { console.log('Location gathering Not allowed') const latitude = 0 // Default Latitude const longitude = 0 // Default Longtitude var data = {'latitude': latitude, 'longitude': longitude, }; data.csrfmiddlewaretoken = $('input[name=csrfmiddlewaretoken]').val(); console.log(data); document.getElementById("LocationLat").innerHTML = "err.latitude"; document.getElementById("LocationLon").innerHTML = "err.longitude"; $.post("/", data); } navigator.geolocation.getCurrentPosition(success,error); } // Location is fetched when user loads screen Window.onload = findLoc(); </script> </body>
问题原因与解决方法
核心问题
当前的POST请求仅向后台发送了GPS数据,但后台返回的新页面内容未被前端接收并替换——$.post("/", data)发送请求后,后台生成了带周边机场的页面,但前端没有处理这个返回结果,页面始终保持GET请求渲染的初始状态。
解决步骤
1. 修改视图:区分AJAX请求与普通请求
后台需要判断请求是否为AJAX请求,若是则返回JSON格式的机场数据,而非完整页面;普通GET请求则返回带全部机场的页面。
修改后的views.py:
from django.http import JsonResponse def home_view(request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') if request.method == 'POST': # 识别AJAX请求 if request.headers.get('X-Requested-With') == 'XMLHttpRequest': latitude = float(request.POST.get('latitude')) longitude = float(request.POST.get('longitude')) # 假设getStationInfo返回机场列表数组 airports = aviationweatherapi.getStationInfo(latitude, longitude) print("Get airports list around current GPS location") return JsonResponse({'airports': airports, 'IP': ip}) # 非AJAX POST请求的 fallback 逻辑(按需保留) else: latitude = float(request.POST.get('latitude')) longitude = float(request.POST.get('longitude')) context = aviationweatherapi.getStationInfo(latitude, longitude) print("Get airports list around current GPS location") else: # GET请求返回全量机场页面 context = aviationweatherapi.getStationInfo(None, None) print("Get all airports") context.update({'IP':ip}) return render(request,'acceuil.html',context)
2. 前端修改:接收AJAX数据并更新页面
首先确保acceuil.html中有机场列表容器:
{% block contenu %} <div id="airports-container"> {% for airport in airports %} <div class="airport-item">{{ airport.name }} - {{ airport.code }}</div> {% endfor %} </div> {% endblock %}
然后修改模板中的JS,处理POST请求的返回结果:
const findLoc = () => { const success = (position) => { const latitude = position.coords.latitude; const longitude = position.coords.longitude; var data = {'latitude': latitude, 'longitude': longitude }; data.csrfmiddlewaretoken = $('input[name=csrfmiddlewaretoken]').val(); console.log('Location is on'); console.log(data); document.getElementById("LocationLat").innerHTML = latitude; document.getElementById("LocationLon").innerHTML = longitude; // 发送请求并更新页面 $.post("/", data, function(response) { const container = document.getElementById('airports-container'); container.innerHTML = ''; // 遍历生成新的机场列表项 response.airports.forEach(airport => { const item = document.createElement('div'); item.className = 'airport-item'; item.textContent = `${airport.name} - ${airport.code}`; container.appendChild(item); }); }, 'json'); } const error = () => { console.log('Location gathering Not allowed') const latitude = 0 // Default Latitude const longitude = 0 // Default Longtitude var data = {'latitude': latitude, 'longitude': longitude, }; data.csrfmiddlewaretoken = $('input[name=csrfmiddlewaretoken]').val(); console.log(data); document.getElementById("LocationLat").innerHTML = "err.latitude"; document.getElementById("LocationLon").innerHTML = "err.longitude"; // 错误场景同样更新页面 $.post("/", data, function(response) { const container = document.getElementById('airports-container'); container.innerHTML = ''; response.airports.forEach(airport => { const item = document.createElement('div'); item.className = 'airport-item'; item.textContent = `${airport.name} - ${airport.code}`; container.appendChild(item); }); }, 'json'); } navigator.geolocation.getCurrentPosition(success,error); } // 修复拼写错误与执行逻辑:赋值函数引用而非立即调用 window.onload = findLoc;
3. 额外修复:JS语法错误
原代码中Window.onload = findLoc();存在两个问题:
Window首字母需小写为windowfindLoc()会立即执行函数,应改为window.onload = findLoc;(仅赋值函数引用,页面加载时自动执行)
内容的提问来源于stack exchange,提问作者Heavy PC
相关产品推荐
相关产品推荐

