我试图在一个页面上拥有所有位置功能,例如get users location
,post it to the database
,然后是基于用户输入的公里半径值的filter results
。
我正在获取MultiValueDictKeyError at /connect/ 'latitude'
,因为POST请求将会发生
location = Location(latitude=request.POST['latitude'], longitude=request.POST['longitude'], user = request.user)
什么时候应该去
if request.POST['radius']:
radius_km = request.POST.get('radius', 0)
我研究了如何阻止这种情况发生,并看到我可以做if request.POST['radius']:
来指示发布请求到正确的功能。
不幸的是,这对错误没有帮助。
我错过了什么吗?
views.朋友
class ConnectView(View):
template_name = 'connect/home.html'
def get(self, request, *args, **kwargs):
f = ProfileFilter(request.GET, queryset=Profile.objects.exclude(user=request.user))
context = {
'users': User.objects.exclude(username=request.user),
'friends': Friend.objects.filter(current_user=request.user),
'filter': f,
}
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
location = Location(latitude=request.POST['latitude'], longitude=request.POST['longitude'], user = request.user)
location.save()
if request.POST['radius']:
radius_km = request.POST.get('radius', 0)
queryset = User.objects.annotate(
radius_sqr=pow(models.F('loc__latitude') -
request.user.loc.latitude, 2) + pow(models.F('loc__longitude') -
request.user.loc.longitude, 2)
).filter(
radius_sqr__lte=pow(int(radius_km) / 9, 2)
).exclude(username=request.user)
context = {'users': queryset}
return JsonResponse({'message': 'success'})
home.html的
<script>
var pos;
var $demo;
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
$demo.text("Geolocation is not supported by this browser.");
}
}
function showPosition(position) {
pos = position;
var { latitude, longitude } = pos.coords;
$('#btn_submit').attr("disabled", null);
}
$(document).ready(function() {
$demo = $("#demo");
$('#btn_submit').on('click', function() {
var data = pos.coords;
data.csrfmiddlewaretoken = $('input[name=csrfmiddlewaretoken]').val();
$.post('', data, function() {
alert("Location Confirmed!");
});
});
});
</script>
<h1>Connect with people.</h1>
<!-- GET window.location IP Address / lat lon coordinates -->
<p id="demo"></p>
<button onclick="getLocation()" class="btn btn-warning" id="confirm">1. Find Location</button>
<button type="submit" id="btn_submit" name="btn_submit" class="btn btn-success" disabled>2. Submit Location </button>
<!-- filter by profile attributes -->
<form method="GET">
{{ filter.form }}
<button type="submit" class="small">Search.</button>
</form>
<!-- enter radius to filter by location-->
<form method="POST">
{% csrf_token %}
<input type="number" name="radius">
<input type="submit" value="filter by kilometers">
</form>
request.POST
只是一个python字典(几乎,它可以有相同键的多个值,因此类名称MultiValueDict
)。所以只需将其视为普通字典对象:
dict[key]
不存在,KeyError
提出了key
dict.get(key)
返回key
或None
的值,如果它不存在的话。dict.get(key, default)
不存在,key
将返回default
的key
的值。如果这些键不在POST参数中,request.POST['latitude']
,request.POST['longitude']
和request.POST['radius']
将抛出此异常。在检查提交内容时始终使用request.POST.get(param_name)
。
在你的情况下,你还应该在使用if 'latitude' in request.POST and 'longitude' in request.POST
和latitude
做任何事情之前添加一个longitude
子句。
在你的post方法中,你添加了request.POST['latitude']
,你可能没有使用post方法传递。而你的if..
状况就在那之后。因此Django会给你错误,因为它没有找到任何带有这个名字的参数,并且会停止进一步的执行。
因此,如果您没有传递纬度经度参数,请在发布请求时尝试将其写为:
request.POST.get('latitude', None)
要么,
在访问if..
和latitude
参数之前放置你的longitutde
条件。