首页 > 解决方案 > 尝试通过 ajax(fetch) 在 django 中保存数据时出错

问题描述

我有一个引用其他模型的模型,我正在尝试使用 ajax 保存数据

例子:

class Friend(models.Model):
    name = ...

class Main(models.Model):
    name = ....
    friend = models.ForeignKey(Friend, on_delete=models.CASCADE)

所有正文都来自 ajax(fetch) 请求

我有一个表格(html),并将数据添加到单元格,然后使用 enter 事件发送数据。

像这样:

input.addEventListener("keyup", function (e) {
  //in this scenario I already have the whole row
  // get full_row `row_data`
  post_ajax = {
    method: "POST",
    headers: {
      "X-CSRFToken": crf_token, // I get it with a regular expression
      "Content-Type": "application/json",
      "X-Requested-With": "XMLHttpRequest",
      Accept: "application/json",
    },
    body: JSON.stringify(row_data),
  };

  fetch("my_url", post_ajax)
    .then((res) => res.json())
    .catch((error) => console.error("Error:", error))
    .then((response) => console.log("Success:", response));
});

我的视图功能

def save_post(request):
    if request.is_ajax and request.method == "POST":
        body_unicode = request.body.decode('utf-8')
        data = json.loads(body_unicode)      
        print('here the data arrives',data)
        # here the data arrives {'name': 'Ale', 'friend_id': 22}
        Main.objects.create(name=data['name'], friends=data['friend_id'])

        return JsonResponse({"instance": data}, status=200)

    return JsonResponse({"error": ""}, status=400)

这是错误

raise TypeError("%s() got an unexpected keyword argument '%s'" %
                (cls.__name__, kwarg))
TypeError: Main() got an unexpected keyword argument 'Friends'

有什么想法或建议吗?

标签: pythondjangoajaxdjango-models

解决方案


编辑:

在创建Main对象时,尝试将“ friend”属性设为对象,如下所示:

friend = Friend.objects.get(id=data['friend_id'])
Main.objects.create(name=data['name'], friend=friend)

此外,主要问题似乎是您将列称为“朋友”,但在创建对象时它应该是“朋友”。Main

这个:

 Main.objects.create(name=data['name'], friends=data['friend_id'])

应该:

 Main.objects.create(name=data['name'], friend=data['friend_id'])

以前的答案:

假设您在模板中使用 JQuery 来发送 AJAX 请求,因为您没有指定。

在您的 urls.py 中:

...
path('/api/post_friend/', post_friend_api, name="post_friend_api"),
...

在您的模板中:

<script type="text/javascript">
        $("#myBurron").click(function(){
            var csrfToken = $( "input[name='csrfmiddlewaretoken']"); // assuming this is a form
            var friend_name = $("#friend_name").val();
                $.ajax({ url: '{% url 'post_friend_api' %}',
                                    type: "POST",
                                    dataType: "json",
                                    data: {'friend':friend_name, 'csrfmiddlewaretoken':csrfToken.val()},
                                    cache: false
                           }).done(function(data) {
                                if (data.result === true){
                                    alert(data.message);
                               }
                           });
                      });
                  });
            </script>

在你的views.py中:

        from django.http import JsonResponse

        def post_friend_api(request):
              data = {}
              if request.POST.get('friend', None) is not None:
                  friend_name = request.POST.get('post_note')
                  # save the object and indicate success
                  data['result'] = True
                  data['message'] = "Friend saved successfully"
                  ...
              if request.is_ajax():
                 return JsonResponse(data)
              else:
                 return HttpResponseBadRequest()

当您通过 POST 发送数据时,请不要忘记传递您的 CSRF 令牌,如上例所示。这假设您在页面上有一个可以从中获取它的表单,否则您可以使用类似这样的东西来获取它:

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

如果您不想处理 CSRF 令牌,您可以用@csrf_exempt装饰器标记视图并csrfmiddlewaretoken从模板中的 Ajax 调用中删除 ' ' 数据元素,但这可能不是理想的或最安全的。一个例子:

    from django.views.decorators.csrf import csrf_exempt
    from django.http import JsonResponse

    @csrf_exempt()
    def post_note_api(request):
           ...

如果您发布更多详细信息,我可以更新我的答案。


推荐阅读