You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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首字母需小写为window
  • findLoc()会立即执行函数,应改为window.onload = findLoc;(仅赋值函数引用,页面加载时自动执行)

内容的提问来源于stack exchange,提问作者Heavy PC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:24:57