django-rest-framework POST 上的“此字段是必需的”

2024-01-27

每当我发布到 django-rest-framework (DRF) 端点时,我都会不断收到"HTTP 400 Bad Request" {"offeror_organization":["This field is required."]}回复。但是,考虑到下面的卷曲示例,我明确指定了一个值。

无论内容类型如何(application/json、application/x-www-form-urlencoded、multipart/form-data),都会发生这种情况。它唯一起作用的时候是当我使用 DRF Web 界面上的“HTML 表单”(相对于“原始数据”)选项卡提交时。

有一些类似的帖子(比如this https://stackoverflow.com/questions/24074089/django-rest-framework-field-is-required-error/24076123 and this https://stackoverflow.com/questions/30802785/django-rest-framework-this-field-is-required-only-when-posting-json-not-when),但似乎没有一个解决方案对我有用。

Model:

class OrganizationManager(models.Manager):
    def get_by_natural_key(self, offeror_organization):
        return self.get(offeror_organization=offeror_organization)

class Organization(models.Model):
    idorganization = models.AutoField(primary_key=True)
    offeror_organization = models.CharField(max_length=250, null=False, blank=False, verbose_name='Offeror Organization')
    created_at = models.DateTimeField(auto_now_add=True, null=False)
    updated_at = models.DateTimeField(auto_now=True, null=False)

    objects = OrganizationManager()

    def natural_key(self):
        return "%s" % (self.offeror_organization)

    def __str__(self):
        return self.offeror_organization

序列化器:

class OrganizationSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Organization
        fields = ['offeror_organization']

    # I've tried both with and without a create function
    def create(self, validated_data): 
        organization_data = validated_data.pop('offeror_organization', None)
        if organization_data:
            organization = Organization.objects.get_or_create(**organization_data)[0]
            validated_data['offeror_organization'] = organization

视图/api.py:

from webapp.models import Organization
from webapp.serializers import OrganizationSerializer

from rest_framework import viewsets

class OrganizationViewSet(viewsets.ModelViewSet):
    queryset = Organization.objects.all().order_by('offeror_organization')
    serializer_class = OrganizationSerializer

urls.py:

from django.urls import include, path
from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r'organization', views.OrganizationViewSet)

urlpatterns = [
    ...
    path('api/', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]

卷曲命令:

curl -X POST -H 'Content-Type: application/json' -d '{"offeror_organization":"Test2"}' 10.101.10.228:29000/webapp/api/organization/

settings.py 中间件:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'csp.middleware.CSPMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware'
]

设置.py REST_FRAMEWORK

# currently have all API authentication disabled while troubleshooting this issue
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [],
    'DEFAULT_PERMISSION_CLASSES': [],
}

就我而言,解决这个问题需要围绕一些不同的实现限制进行“机动”。

nginx + uWSGI 套接字 + Django REMOTE_USER 身份验证: 正如这篇文章的评论/聊天中提到的,我在 Django 应用程序前面有一个 nginx 代理和一个 uWSGI 应用程序服务器。既然我依赖REMOTE_USER 身份验证 https://docs.djangoproject.com/en/3.2/howto/auth-remote-user/,我的 uwsgi/nginx 配置must使用 uWSGI 套接字(相对于 http),以便我可以将 REMOTE_USER 作为环境变量从 nginx 传递到 Django。当使用http(与nginx proxy_pass耦合)时,虽然proxy_pass可以设置标头或cookie,但这些似乎无法转换为Django(需要环境变量)。

我认为在尝试 POST 到使用 uWSGI 套接字服务的 Django/DRF 应用程序时存在一些问题。根据 uWSGI要知道的事情(最佳实践) https://uwsgi-docs.readthedocs.io/en/latest/ThingsToKnow.html, “TL/DR:如果您打算直接向公众公开 uWSGI,请使用 --http,如果您想在后端使用 http 的网络服务器后面代理它,请使用 --http-socket”。就我而言,同时拥有 Web 应用程序和基于 DRF 的 API(我希望其他服务和系统与之通信),我两者都需要!作为一种(希望是暂时的)解决方法,我目前正在生成twouWSGI 进程 - 一个使用--socket,以及一个使用--http(用于 API POST 调用)。如果您在使用 ---socket 时进行 POST,您可能会收到 DRF 的空响应错误。

顺便说一句,我最初看到了利用 uwsgi_curl 的一些“承诺”(来自uwsgi_工具 https://github.com/andreif/uwsgi-tools)通过 uWSGI 套接字进行 POST(这导致了“字段为必填项“错误(相对于空响应错误),但那就是我开始遇到第二个问题的时候......

POST 嵌套 application/json 并同时上传文件:帖子中引用的“组织”模型主要是概念验证,因为它是我的 Django 应用程序中最简单的模型。实际上,我需要通过嵌套序列化发布到更复杂的模型,因为该模型包含其他模型的外键。但这完全可以通过 DRF 实现。Except就我而言,我的模型属性之一是 FileUpload 字段。正如其他 SO 问题中所述(例如this https://stackoverflow.com/questions/19439961/python-requests-post-json-and-file-in-single-request/35946962一),尝试 POST 时也存在一些问题嵌套(即不是“扁平”)application/json 在单个请求中上传文件。虽然我永远无法完全理解正在发生的问题(至少使用drf_writable_nested.serializers.WritableNestedModelSerializer在我的例子中),我通过编写自己的自定义序列化器(serializers.Serializer)简化了手头的问题,这样我就可以避免嵌套 JSON 对象(例如我的 { "offeror_organization": {"offeror_organization: "Test"}} POST 请求。这解决了我的问题。

使用自定义序列化程序来缓解嵌套 JSON + 文件上传问题后,我敢打赌 uwsgi_curl POST 会起作用。尽管外部客户端系统/服务仅限于使用该 Python 包。无论如何,一旦尝试我就会更新我的答案。感谢@Michael 的评论并帮助我走上正确的“道路”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

django-rest-framework POST 上的“此字段是必需的” 的相关文章

  • 在 Django 中使用 prefetch_lated 连接 ManyToMany 字段

    我可能遗漏了一些明显的东西 但我在连接 ManyToMany 字段以在 Django 应用程序中工作时遇到问题 我有两个模型 class Area models Model name CharField class Role models
  • Django 不显示更新的 css 文件

    因此 我使用 sass 来更新我的 Django 站点 并使用 git 来对整个内容进行版本控制 我最近对 CSS 文件进行了更新 其中存在一些严重错误 Sass 编译了更改 然后我将新版本推送到服务器 我查看了服务器 新的 css 文件实
  • 在 django vanilla CreateView 上设置当前用户

    我想用当前登录的用户更新我的模型 我正在使用 django vanilla views 为了存储新记录 我尝试使用 CreateView 我不想在表单上显示用户 只需自动更新即可 这是我的模型 class Measurement model
  • Django - 具有自动完成功能的 Javascript 动态内联 FormSet

    我正在尝试制作一种能够附加参与者的调度程序事件编辑器 Models class Session models Model start time models DateTimeField end time models DateTimeFie
  • Django:如何测试“HttpResponsePermanentRedirect”

    我正在为我的 django 应用程序编写一些测试 在我看来 它使用 HttpResponseRedirect 重定向到其他一些网址 那么我该如何测试呢 姜戈TestCase类有一个方法assertRedirects https docs d
  • 如何在没有 openshift 的情况下托管 Django localhost 应用程序?

    我已经在本地主机中创建了一个 Django 应用程序 现在我需要在互联网上托管 我已经尝试过开档 https www openshift com and 任何地方的Python https www pythonanywhere com也 但
  • 如何限制Django CreateView中ForeignKey字段的选择?

    我有一个沿着这些思路的模型结构 models py class Foo models Model class Bar models Model foo models ForeignKey Foo class Baz models Model
  • matplotlib matshow 标签

    我一个月前开始使用 matplotlib 所以我仍在学习 我正在尝试用 matshow 制作热图 我的代码如下 data numpy array a reshape 4 4 cax ax matshow data interpolation
  • 在 django 查询集上使用 iterator()

    我最近遇到了一些奇怪的行为 需要检查我的理解 我在模型中使用一个简单的过滤器 然后迭代结果 e g allbooks Book objects filter author A A Milne for book in allbooks do
  • 带摘要的 php curl 返回两个响应

    我发现了一个 奇怪 的 php CURL 行为 这让我抓狂 基本上我正在做的是使用curl 进行摘要身份验证的调用 这是我的代码的摘录 curl setopt this gt c CURLOPT HTTPAUTH CURLAUTH DIGE
  • Django modelForm 中的文件上传

    我正在尝试在 appengine django 中上传文档 使用纯 django 代码成功上传文档 使用 python manage py runsever 但是当我尝试使用 appengine 项目运行 django 时 它给了我错误 E
  • Django 本身支持迁移吗

    我听说所有新的 Web 框架 如 ROR Django 等 都遵循敏捷和 TDD 的一般原则 遵循敏捷和 TDD 的一部分是在从一个迭代到另一个迭代时制定自己的设计 这意味着模型及其架构将随着应用程序的不同版本而演变 我知道 ROR 本身支
  • Twitch API - 无法使用 PHP 获取身份验证令牌

    stackoverflow 的成员们大家好 我不是一个喜欢寻求帮助的人 但在这种情况下 我认为这是解决我的问题的唯一方法 谷歌并没有给我太大帮助 所以 我的问题 我想使用 Twitch API 获取一些数据 听起来很容易 我希望是这样 下面
  • django 模板上的 vscode html 自动套用格式

    我喜欢 VSCode 的保存自动格式功能 直到它弄乱了我的模板代码 它错误地将我的 django 模板语法格式化为一行代码 有时非常长的一行 所以不用这段代码 for row in ABCDEFGH tr for col in 123456
  • Django-celery/RabbitMQ 在哪里存储任务结果?

    我的 celery 数据库后端设置是 CELERY RESULT BACKEND database CELERY RESULT DBURI mysqlite db 我使用 RabbitMQ 作为我的消息发送器 似乎没有任何结果存储在数据库中
  • 过滤 django 中的组合日期和时间

    我有一个日期和时间分开的模型 我想过滤未来的事件并最终写了这个 这并不酷 有更好的方法吗 我可以以某种方式使用combine 和min 来实现这一点吗 正如您在查询中看到的 它必须包含 time gt now 的今天事件 future ev
  • 在 python3.6 上 pip 安装 Django

    如果我跑pip install Django I get 已满足的要求 Django in usr local lib python2 7 dist packages 我想改用 python3 6 它已经安装在 usr bin python
  • Django 模型同步表

    如果我更改 Django 模型中的字段 如何将其与数据库表同步 我是否需要在数据库上手动执行此操作 或者是否有工具可以帮助完成此过程 唉 Django 不支持任何简单的解决方案 django 唯一能为你做的就是使用与新模型匹配的新表重新启动
  • 构建一个两阶段的 Django 管理表单来添加对象?

    是否可以构建一个两阶段表单来在 Django admin 中创建对象 当管理员用户访问时 admin my app article add 我想显示一些选项 然后 应用程序将显示创建页面 其中包含基于所做选择的预先计算的字段 你可以覆盖ad
  • 使用factoryboy将字段保存为JSON

    我正在尝试创建模型的一个实例 其中一个字段是JSONField 通过创建模型实例时factoryboy 我想将该字段保存为测试数据库中的 JSONField 简单地将字段传递为JSON 它被存储在Unicode数据类型 我被困在这个问题上

随机推荐