每当我发布到django rest framework(DRF)endpoint时,我都会不断收到“HTTP 400错误请求”{“报价人组织”:[“此字段是必需的”。]}
响应。但是,考虑到下面的curl示例,我显然指定了一个值。
无论Content-Type(应用程序/json、应用程序/x-wow-form-urlencoded、多部分/form-data)如何,都会发生这种情况。它唯一有效的时间是当我使用DRF网络界面上的“超文本标记语言表单”(相对于“原始数据”)选项卡提交时。
有一些类似的SO帖子(像这样和这样),但是没有一个解决方案似乎对我有用。
型号:
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'
]
settings.py REST\u框架
# currently have all API authentication disabled while troubleshooting this issue
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [],
'DEFAULT_PERMISSION_CLASSES': [],
}
我有相同的设置(nginx gunicorn django rest framework drf writeable nested),但我可以为包含多部分/表单数据的POST请求找到一种有效的格式:
它必须是这样的:
JSON:
{
'name': 'test-name',
'files': [
{
'file': 'test-file-1'
},
{
'file': 'test-file-2'
},
...
],
...
}
必须格式化为:
表单数据:
name: test-name
files[0]file: test-file-1
files[1]file: test-file-2
...
一些库会在嵌套列表的方括号后使用点,这将导致
此字段为必填项
错误。或者,列表括号之后的另一个括号也会导致相同的错误。这是错误的:文件[0]。文件
这也是错误的:文件[0][file]
我的示例假设以下Django类:
# views.py
from rest_framework.viewsets import ModelViewSet
from rest_framework.parsers import MultiPartParser, FormParser
from .serializers import YourCustomModelSerializer
class YourCustomModelViewSet(ModelViewSet):
queryset = YourCustomModel.objects.all()
parser_classes = [FormParser, MultiPartParser]
permission_classes = []
serializer_class = YourCustomModelSerializer
# serializers.py
from rest_framework.serializers import ModelSerializer
from drf_writable_nested.serializers import WritableNestedModelSerializer
from .models import YourCustomModel, File
class FileSerializer(ModelSerializer):
class Meta:
model = File
fields = ['file']
class YourCustomModelSerializer(WritableNestedModelSerializer):
# Reverse foreign key
files = FileSerializer(many=True)
class Meta:
model = YourCustomModel
read_only_fields = ('id', )
fields = [
'id',
'name',
'files'
]
# models.py
from django.db import models
class File(models.Model):
file = models.FileField()
class YourCustomModel(models.Model):
name = models.CharField(max_length=200)
我使用下面的javascript/typecript前端代码将我的json数据打包到FormData请求中:
const requestBody = {
name: 'test-name',
files: [
{ file: file1 }, // File object
{ file: file2 }, // File object
{ file: file3 } // File object
]
}
// # use your own code to serialize the above javascript dict/json/object
// into form-data object (I used the library https://www.npmjs.com/package/object-to-formdata but I had to write a patch for the exact reason described above: files[0].file is not correctly parsed by Django and files[0][file] also won't work, therefore I slightly changed the library code so that it will format my object to files[0]file for every nested item:
// 2. prepare a serializer-library to convert the dict into a special form which can be parsed by django.
const options = {
indices: true,
allowEmptyArrays: true,
useDotOrBracketsOrNothingForNestedObjects: 2 // Option 0: DOT-Notation, 1: Brackets, 2: Nothing (this option is from my custom patch)
}
// use npx patch: https://stackoverflow.com/a/62567504/3433137
// (I patched this serialize library and the patch is somewhere stored as a file in this project)
const formData = serialize(
requestBody,
options
)
// 3. upload the data
api.post(url, formData)
在我的例子中,解决这个问题需要围绕几个不同的实现约束进行“操作”。
nginx uWSGI Socket Django REMOTE_用户身份验证:如本文评论/聊天中所述,我的Django应用程序前面有一个nginx代理和一个uWSGI应用程序服务器。由于我依赖于远程_用户身份验证,因此我的uwsgi/nginx配置必须使用uwsgi套接字(vs.http),以便我可以将远程_用户作为环境变量从nginx传递到Django。使用http(耦合w/nginx proxy\u pass)时,虽然proxy\u pass可以设置头或cookie,但这些头或cookie似乎无法转换为Django(需要环境变量)。
我认为当试图发布到使用uWSGI套接字服务的Django/DRF应用程序时,会有一些问题。根据uWSGI要知道的事情(最佳实践),“TL/DR:如果您计划直接向公众公开uWSGI,请使用超文本传输协议,如果您想在使用后端的超文本传输协议的网络服务器后面代理它,请使用超文本传输协议-套接字”。在我的例子中,同时拥有一个Web应用程序和一个基于DRF的API(我希望其他服务和系统可以与之交谈),我需要两者!作为一个(希望是暂时的)解决方案,我目前正在生成两个uWSGI进程——一个使用-套接字
,一个使用-超文本传输协议
(用于API POST调用)。如果您在使用---套接字时发布,您可能会从DRF获得空响应错误。
顺便说一句,我最初在uWSGI套接字上使用uwsgi_curl(从uwsgi_tools)到POST时看到了一些“promise”(这导致了“字段是必需的”错误(相对于空响应错误),但那时我开始遇到我的第二个问题...
POST嵌套应用程序/json w/同步文件上传:文章中引用的“组织”模型主要是概念验证,因为它是我的Django应用程序中最不复杂的模型。实际上,我需要发布到一个更复杂的嵌套序列化模型,因为模型包含其他模型的外键。但DRF完全可以做到。除了在我的情况下,我的模型属性之一是FileUpload字段。正如其他SO问题(如本问题)所指出的,在尝试通过单个请求中的文件上传来发布嵌套(即不是“平面”)的应用程序/json时也存在一些问题。虽然我从未能够完全理解这个问题(至少在我的情况下使用了drf_writable_nested.serializers.WritableNestedModelSerializer
),但我通过编写自己的自定义Serializer(序列化器)简化了手头的问题。序列化器),这样我就可以避免在我的POST请求中嵌套JSON对象(如{"offeror_organization":{"offeror_organization:"Test"}}。这解决了我的问题。
有了自定义序列化程序来缓解嵌套JSON文件上载问题,我敢打赌uwsgi_curl帖子会起作用。尽管如此,外部客户机系统/服务仅限于使用该Python包。无论如何,我会在尝试后更新我的答案。感谢@Michael的评论,并帮助我走上正确的“道路”。
从文件中: read_only将其设置为True,以确保在序列化表示时使用该字段,而在反序列化期间更新实例时不使用该字段。 默认为假 required通常情况下,如果反序列化期间未提供字段,则会引发错误。如果反序列化过程中不需要此字段,则设置为false。 默认为True。 因此,我有一个模型,其中有一个字段不可为null,但我希望在pre_save方法中填充它,因此我在serializer中将该
当我要求一个图像http://127.0.0.1:8000/api/images/1/或者传入参数进行裁剪http://127.0.0.1:8000/api/images/1/?height=320 我得到的答复是: 而在http://127.0.0.1:8000/api/images/ 答复是: 为什么缩略图不容易返回主机名,我如何将基本网址追加到响应中? 以下是我的看法。派克
主要内容:PHP - 必需字段,PHP - 显示错误信息本章节我们将介绍如何设置表单必需字段及错误信息。 PHP - 必需字段 在上一章节我们已经介绍了表的验证规则,我们可以看到"名字", "E-mail", 和 "性别" 字段是必需的,各字段不能为空。 字段 验证规则 名字 必需。 + 只能包含字母和空格 E-mail 必需。 + 必需包含一个有效的电子邮件地址(包含"@"和".") 网址 可选。 如果存在,它必需包含一个有效的URL 备注 可选。多
我已将数据注释添加到ASP中的一个模型中。NETMVC应用程序。创建迁移后,运行命令会导致以下错误: 无法将值NULL插入表“MOVICES”的“Director”列中。dbo。电影;;列不允许空值。更新失败。声明已终止。 这是由于某些记录的列中有NULL。如何将这些值自动更改为某个默认值(例如“John Doe”)控制器? 这是我的模型: 以下是我的最新迁移:
我有以下API定义: 我定义了txConfig is required属性(这是类),但当发送空JSON()时,spring boot仍然运行API,而我希望它返回一个错误,即未设置参数tsConfig。 知道我错过了什么吗? 编辑:使用@Valid和@NotNull解决了它,但是返回的错误信息太多,有办法修复吗?
我想我会在这里问这个问题,因为我不太确定我会错在哪里。我正在尝试使用Django Rest框架类通过AJAX执行POST请求。但是,每当事件触发时,我都会收到以下错误: 这是堆栈跟踪中显示的内容: 上下文 我试图做到这一点,当用户单击“添加到列表”按钮时,它会向用户定义的列表发送一个cafeName(以及最终的其他详细信息)。 我想知道是否有人可以看看我的代码,并给我一些指导,我哪里出了问题? 代