【问题标题】:Django save and enter data after API call in viewsDjango在视图中调用API后保存并输入数据
【发布时间】:2018-07-04 05:43:40
【问题描述】:

我有 2 个 django 项目,D1 和 D2。 D1 有一个表调用 T1,D2 有一个表调用 T2。

所以我在 D1 中有一个视图,它对 D2 中的 api 进行 api 调用,并将我在 POST 请求后获得的值保存到 T1 中。但我也希望能够在表 T1 的其他字段中输入数据。

示例:t2 只有book 字段,t1 有bookauthor 字段。当 D1 在 D2 中对 t2 执行 post 方法时,它将返回一个 book 值,该值将保存到 t1 但我也希望用户自己输入 author。我该怎么做 ?

这是我的代码

models.py

在第一天:

class T1(models.Model):
    book = models.CharField(max_length=10, blank=True, null=True)
    author = models.CharField(max_length=10, blank=True, null=True)

在 D2 中

class T2(models.Model):
    book = models.CharField(max_length=10, blank=True, null=True)

views.py

@csrf_exempt
def my_django_view(request):
    if request.method == 'POST':
        r = requests.post('http://127.0.0.1:8000/api/test/', data=request.POST)
    else:
        r = requests.get('http://127.0.0.1:8000/api/test/', data=request.GET)

    if r.status_code == 201 and request.method == 'POST':
        data = r.json()
        testsave_attrs = {
            "book": data["book"],
        }
        testsave= T1.objects.create(**testsave_attrs)
        return HttpResponse(r.text)
    elif r.status_code == 200:  # GET response
        return HttpResponse(r.json())
    else:
        return HttpResponse('Could not save data')

【问题讨论】:

  • 真的,真的,不要从您的应用向其自身发出 POST 请求。
  • 那你有什么建议呢?因为它正在使用来自另一个项目的 API

标签: django django-rest-framework


【解决方案1】:

我相信您可以在向my_django_view 发出的同一个 POST 请求中简单地做到这一点。您可以将request.POST 视为字典。它基本上有请求中所有用户输入的键值对,可能还有你的 CSRF 令牌之类的东西。在任何情况下,在您的前端,您都希望有一个表单或一些东西要发送,以及您现有的其他 request.POST 数据,以便您可以将其提取到您的视图中。

@csrf_exempt
def my_django_view(request):

    author = None  # let author be None at the start

    if request.method == 'POST':
        post_data = request.POST.copy()  # make a copy
        author = post_data.dict().pop("author", None)  # Extract out the author here and remove it from request.POST
        r = requests.post('http://127.0.0.1:8000/api/test/', data=post_data)
    else:
        r = requests.get('http://127.0.0.1:8000/api/test/', data=request.GET)

    if r.status_code == 201 and request.method == 'POST':
        data = r.json()
        testsave_attrs = {
            "book": data["book"],
            "author": author
        }
        # You should probably do some validation that author is not None here
        # before you actually attempt to create T1.
        # You could do it here or anywhere else before creating T1.
        testsave= T1.objects.create(**testsave_attrs)
        return HttpResponse(r.text)
    elif r.status_code == 200:  # GET response
        return HttpResponse(r.json())
    else:
        return HttpResponse('Could not save data')

【讨论】:

  • 我在尝试后得到了这个错误。 raise AttributeError("This QueryDict instance is immutable") AttributeError: This QueryDict instance is immutable此行出现此错误author = request.POST.pop("author", None)
  • 啊,是的,只需复制一份 - 我已经更新了我的答案,还要注意您的 requests.post 也需要使用复制的数据。
  • 它有效。但是保存后查看T1表api的结果,作者的结果似乎很奇怪。 "author": "['new']" 而不是 "author": "new"
  • 您的数据在保存之前是什么样子的 - authorauthor = post_data.pop("author", None) 行中返回什么?当您查看 T1 时,您看到的完整结果是什么?
  • 我更新了答案,注意author = post_data.dict().pop("author", None)这一行——我们需要先将其转换为python dict,以便它从列表中提取if。 Django 的QuerySet 旨在检索同一键的多个值,因此所有内容都将存在于列表中。由于我们自己提取它,我们需要记住将其转换为 python 字典,Django 将帮助您从列表中提取单个值。
猜你喜欢
  • 2018-07-03
  • 2018-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
相关资源
最近更新 更多