/ connect /处的MultiValueDictKeyError

时间:2019-02-15 12:08:40

标签: django django-views

我正在尝试将所有位置功能都放在一页上,例如 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.py

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>

2 个答案:

答案 0 :(得分:2)

在您的post方法中,您添加了<script src="https://code.jquery.com/jquery-2.0.3.min.js"></script> <script src="https://unpkg.com/cytoscape@3.1.0/dist/cytoscape.min.js"></script> <script src="https://unpkg.com/cytoscape-cose-bilkent@4.0.0/cytoscape-cose-bilkent.js"></script> <script src="https://cdn.jsdelivr.net/npm/cytoscape.js-undo-redo@1.0.1/cytoscape-undo-redo.js"></script> <script src="https://unpkg.com/cytoscape-expand-collapse@3.1.1/cytoscape-expand-collapse.js"></script> <div> <input id="switch" type="checkbox" onclick=switchHandler(this)>Layout without cytoscape-expand-collapse</input> </div> <div id="cy"></div>,您可能没有通过post方法传递它。然后您的request.POST['latitude']条件随之而来。因此Django给您错误,因为它找不到具有该名称的任何参数,并且将停止进一步执行。

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

if..

在访问request.POST.get('latitude', None)if..参数之前输入您的latitude条件。

答案 1 :(得分:1)

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

    如果dict[key]不存在,
  • KeyError会引发key
  • dict.get(key)返回keyNone的值(如果不存在)。
  • 如果dict.get(key, default)不存在,
  • key返回default的{​​{1}}的值。
如果这些键不在POST参数中,则

keyrequest.POST['latitude']request.POST['longitude']将引发此异常。检查正在提交的内容时,请始终使用request.POST['radius']

对于您来说,在使用request.POST.get(param_name)if 'latitude' in request.POST and 'longitude' in request.POST做任何事情之前,还应该添加一个latitude子句。