我一直在使用 Django 和 djangorestframework 撰寫 API,以便在 Google App Engine 中進行部署。API 基本上是一個包注冊表,因此您可以使用 API 創建、更新、獲取和洗掉包。
除了一個端點外,所有端點似乎都有效。唯一不起作用的端點是顯示在線注冊表中所有包的分頁串列的端點。
所有端點都在作業,但出于某種原因,當我點擊特定端點“/packages/”時,GCP 給了我錯誤
400. That’s an error.
Your client has issued a malformed or illegal request. That’s all we know
當我在計算機上本地運行該應用程式時,所有端點都運行良好。當我在 Google App Engine 上部署該應用程式時,該應用程式只會停止為該特定路由作業。API 負載應該是:
[ { “姓名”: ”*” } ]
我對這個完全迷失了,希望得到任何幫助。
視圖檔案
import django.db.utils
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.core.paginator import Paginator, EmptyPage
import registry.models
from .serializers import *
from .models import *
# Create your views here.
@api_view(['GET'])
def apiOverview(request):
api_urls = {
'List': '/package-list/',
'Create': '/package-create/',
'Update': '/package-update/',
'Delete': '/package-delete/',
'Rate': '/package-rate/',
'Download': '/package-download/'
}
return Response(api_urls)
@api_view(['GET'])
def packages_middleware(request):
print(request)
print(type(request))
print(request.data)
print(type(request.data))
# determine offset query parameter
offset = request.GET.get('Offset')
if offset is None:
offset = 0
else:
offset = int(offset)
# capturing request body
response = []
queries = request.data
if len(queries) < 1:
return Response({'message: empty request body array'}, status=400)
else:
if len(queries) == 1 and queries[0]['Name'] == '*':
response = list(PackageMetadata.objects.all().values())
else:
for query in queries:
if 'Name' in query.keys() and 'Version' in query.keys():
for x in list(PackageMetadata.objects.filter(Name__icontains=query['Name']).filter(
Version__contains=query['Version']).values()):
response.append(x)
else:
response.append({
'message': 'query {q} is missing at least one attribute - remember to check spelling and capitalization'.format(q=query)
})
paginator = Paginator(response, 10)
try:
return Response(paginator.page(offset 1).object_list, headers={'Offset': offset 1})
except EmptyPage:
return Response(paginator.page(1).object_list, headers={'Offset': 2})
@api_view(['GET', 'PUT', 'DELETE'])
def package_middleware(request, pk):
try:
package = Package.objects.get(Metadata__ID__exact=str(pk))
if request.method == 'GET':
# CHECK THAT CONTENT FIELD IS SET
serializer = PackageSerializer(package, many=False)
return Response(serializer.data, status=200)
elif request.method == 'PUT':
payload = request.data
if 'Metadata' in payload and 'Data' in payload:
if payload['Metadata'] != PackageMetadataSerializer(package.Metadata, many=False).data:
return Response({"message": "name, version and ID must match"}, status=400)
else:
# CHECK THAT ONLY ONE DATA FIELD IS SET
serializer_data = PackageDataSerializer(data=payload['Data'], many=False)
if serializer_data.is_valid(raise_exception=True):
try:
serializer_data.update(instance=package.Data, validated_data=serializer_data.validated_data)
except django.db.utils.IntegrityError:
return Response(
{"message": "both Content and URL must be included in query, but exactly one can be set"},
status=400)
return Response(status=200)
else:
return Response(
{"message": "incorrect request body schema - remember to check spelling and capitalization"},
status=400)
else:
package.Metadata.delete()
package.Data.delete()
package.delete()
return Response({"message": "package deleted"}, status=200)
except registry.models.Package.DoesNotExist:
return Response({"message": "package not found"}, status=400)
@api_view(['POST'])
def create_package_middleware(request):
payload = request.data
print(payload)
if 'Metadata' in payload and 'Data' in payload:
serializer_metadata = PackageMetadataSerializer(data=payload['Metadata'], many=False)
serializer_data = PackageDataSerializer(data=payload['Data'], many=False)
if serializer_data.is_valid(raise_exception=True) and serializer_metadata.is_valid(raise_exception=True):
try:
metadata = PackageMetadata.objects.create(ID=serializer_metadata.data.get('ID'),
Name=serializer_metadata.data.get('Name'),
Version=serializer_metadata.data.get('Version'))
except django.db.utils.IntegrityError:
return Response({"message": "duplicate key-value (Name, Version) violates uniqueness constraint"},
status=403)
try:
data = PackageData.objects.create(Content=serializer_data.data.get('Content'),
URL=serializer_data.data.get('URL'))
except django.db.utils.IntegrityError:
metadata.delete()
return Response(
{"message": "both Content and URL must be included in query, but exactly one can be set"},
status=400)
Package.objects.create(Data=data, Metadata=metadata)
serializer_metadata = PackageMetadataSerializer(metadata, many=False)
return Response(serializer_metadata.data, status=200)
else:
return Response({"message": "incorrect request body schema - remember to check spelling and capitalization"},
status=400)
@api_view(['DELETE'])
def byName_middleware(request, name):
if name == '*':
return Response({"message": "query name reserved"}, status=400)
querySet = Package.objects.filter(Metadata__Name__iexact=name)
if len(querySet) == 0:
return Response({"message": "package not found"})
else:
for package in querySet:
package.Metadata.delete()
package.Data.delete()
package.delete()
return Response(status=200)
網址檔案
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.apiOverview),
path('packages/', views.packages_middleware, name='packages_middleware'),
path('package/<str:pk>', views.package_middleware, name='package'),
path('package/', views.create_package_middleware, name='create'),
path('package/byName/<str:name>', views.byName_middleware, name='byName')
]
模型.py
from django.db import models
# Create your models here.
class PackageData(models.Model):
Content = models.TextField(blank=True, null=True) # actual zip file
URL = models.CharField(max_length=500, blank=True, null=True) # url of package
# class Meta:
# constraints = [
# models.CheckConstraint(
# name="%(app_label)s_%(class)s_content_or_url",
# check=models.Q(Content__isnull=True, URL__isnull=False) | models.Q(Content__isnull=False, URL__isnull=True)
# )
# ]
class PackageMetadata(models.Model):
class Meta:
constraints = [
models.UniqueConstraint(fields=['Name', 'Version'], name='unique_package')
]
ID = models.CharField(primary_key=True, max_length=50)
Name = models.CharField(max_length=50)
Version = models.CharField(max_length=50)
class Package(models.Model):
Data = models.ForeignKey(PackageData, on_delete=models.CASCADE)
Metadata = models.ForeignKey(PackageMetadata, on_delete=models.CASCADE)
class PackageRating(models.Model):
BusFactor = models.DecimalField(max_digits=10, decimal_places=9)
Correctness = models.DecimalField(max_digits=10, decimal_places=9)
GoodPinningPractice = models.DecimalField(max_digits=10, decimal_places=9)
LicenseScore = models.DecimalField(max_digits=10, decimal_places=9)
RampUp = models.DecimalField(max_digits=10, decimal_places=9)
ResponsiveMaintainer = models.DecimalField(max_digits=10, decimal_places=9)
class PackageQuery(models.Model):
Name = models.CharField(max_length=50)
Version = models.CharField(max_length=50)
uj5u.com熱心網友回復:
您正在GET呼叫/packages/由路由定義處理的呼叫packages_middleware(request)。
在該函式中,您擁有queries = request.data并且其余的邏輯依賴于queries. 該檔案說request.data用于 POST、PATCH、PUT。如果這是正確的,那么這似乎就是您的錯誤所在。
您可以在該行之前和之后放置一個列印陳述句,然后查看您的應用程式是否在之后列印該陳述句。這將幫助您確認這是否是問題所在。
您還應該列印queries. 由于您實際上并未隨 GET 請求發送正文,因此您的其余邏輯可能會失敗,因為 的值queries不是您所期望的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/361599.html
