/ connect /中的MultiValueDictKeyError

问题描述 投票:0回答:2

我试图在一个页面上拥有所有位置功能,例如get users locationpost 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>
django django-views
2个回答
1
投票

request.POST只是一个python字典(几乎,它可以有相同键的多个值,因此类名称MultiValueDict)。所以只需将其视为普通字典对象:

  • 如果dict[key]不存在,KeyError提出了key
  • dict.get(key)返回keyNone的值,如果它不存在的话。
  • 如果dict.get(key, default)不存在,key将返回defaultkey的值。

如果这些键不在POST参数中,request.POST['latitude']request.POST['longitude']request.POST['radius']将抛出此异常。在检查提交内容时始终使用request.POST.get(param_name)

在你的情况下,你还应该在使用if 'latitude' in request.POST and 'longitude' in request.POSTlatitude做任何事情之前添加一个longitude子句。


2
投票

在你的post方法中,你添加了request.POST['latitude'],你可能没有使用post方法传递。而你的if..状况就在那之后。因此Django会给你错误,因为它没有找到任何带有这个名字的参数,并且会停止进一步的执行。

因此,如果您没有传递纬度经度参数,请在发布请求时尝试将其写为:

request.POST.get('latitude', None)

要么,

在访问if..latitude参数之前放置你的longitutde条件。

© www.soinside.com 2019 - 2024. All rights reserved.