简体   繁体   English

Django错误请求400?

[英]Django bad request 400?

I have read many questions on SO regarding error code 400 and understood that the issue is mainly when the client does not send the json, the api is expecting.我已经阅读了许多关于错误代码 400 的 SO 问题,并了解问题主要是当客户端不发送 json 时,api 正在等待。 However, I am not able to get around my error code 400 issue.但是,我无法解决我的错误代码 400 问题。 I am following this thinkster djangular tutorial, In registering new users section, I am hitting bad request 400.我正在关注这个 thinkster djangular教程,在注册新用户部分,我遇到了错误的请求 400。

views.py视图.py

from rest_framework import permissions, viewsets, status
from rest_framework.response import Response

from authentication.models import Account
from authentication.permissions import IsAccountOwner
from authentication.serializers import AccountSerializer


class AccountViewSet(viewsets.ModelViewSet):
    lookup_field = 'username'
    queryset = Account.objects.all()
    serializer_class = AccountSerializer

    def get_permissions(self):
        if self.request.method in permissions.SAFE_METHODS:
            return (permissions.AllowAny(),)

        if self.request.method == 'POST':
            return (permissions.AllowAny(),)

        return (permissions.IsAuthenticated(), IsAccountOwner(),)

    def create(self, request):
        serializer = self.serializer_class(data=request.data)

        if serializer.is_valid():
            Account.objects.create_user(**serializer.validated_data)

            return Response(serializer.validated_data, status=status.HTTP_201_CREATED)

        return Response({
            'status': 'Bad request',
            'message': 'Account could not be created with received data.'
        }, status=status.HTTP_400_BAD_REQUEST)

Is the create method up here supposed to override the create method in CreateModelMixin Class?这里的 create 方法是否应该覆盖 CreateModelMixin 类中的 create 方法?

Here is my serializers.py这是我的serializers.py

from django.contrib.auth import update_session_auth_hash

from rest_framework import serializers

from authentication.models import Account


    class AccountSerializer(serializers.ModelSerializer):
        password = serializers.CharField(write_only=True, required=False)
        confirm_password = serializers.CharField(write_only=True, required=False)

        class Meta:
            model = Account
            fields = ('id', 'email', 'username', 'created_at', 'updated_at',
                      'first_name', 'last_name', 'tagline', 'password',
                      'confirm_password',)
            read_only_fields = ('created_at', 'updated_at',)

            def create(self, validated_data):
                return Account.objects.create_user(**validated_data)

            def update(self, instance, validated_data):
                instance.username = validated_data.get('username', instance.username)
                instance.tagline = validated_data.get('tagline', instance.tagline)

                instance.save()

                password = validated_data.get('password', None)
                confirm_password = validated_data.get('confirm_password', None)

                if password and confirm_password and password == confirm_password:
                    instance.set_password(password)
                    instance.save()

                update_session_auth_hash(self.context.get('request'), instance)

                return instance

When you create an object using the serializer's .save() method, the object's attributes are set literally.当您使用序列化程序的 .save() 方法创建对象时,对象的属性按字面意思设置。 This means that a user registering with the password 'password' will have their password stored as 'password'.这意味着使用密码“password”注册的用户将其密码存储为“password”。 This is bad for a couple of reasons: 1) Storing passwords in plain text is a massive security issue.这有几个原因很糟糕:1)以纯文本形式存储密码是一个巨大的安全问题。 2) Django hashes and salts passwords before comparing them, so the user wouldn't be able to log in using 'password' as their password. 2) Django 在比较之前对密码进行哈希和盐处理,因此用户将无法使用“密码”作为密码登录。 We solve this problem by overriding the .create() method for this viewset and using Account.objects.create_user() to create the Account object.我们通过覆盖此视图集的 .create() 方法并使用 Account.objects.create_user() 创建 Account 对象来解决此问题。

Really clueless on whats going on...实在是不知道怎么回事……

Try serializer.errors after之后尝试serializer.errors

if serializer.is_valid():
            Account.objects.create_user(**serializer.validated_data)

            return Response(serializer.validated_data, status=status.HTTP_201_CREATED)

Do this will give you the errors like this这样做会给你这样的错误

[{'username': [u'This field cannot be blank.']}, this might help you in finding out what is missing in your request.

BTW, I could have put this in the comments but do not have the privilege yet.顺便说一句,我本可以将其放在评论中,但还没有特权。

I was also getting same problem.我也遇到了同样的问题。 Finally solved, use following code.终于解决了,使用下面的代码。 This will show console errors to understand problem.这将显示控制台错误以了解问题。

views.py视图.py

import json

from django.contrib.auth import authenticate, login, logout

from rest_framework import permissions, status, views, viewsets
from rest_framework.response import Response

from authentication.permissions import IsAccountOwner
from authentication.models import Account
from authentication.serializers import AccountSerializer

from django.http import HttpResponse
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

class JSONResponse(HttpResponse):
    """
    An HttpResponse that renders its content into JSON.
    """
    def __init__(self, data, **kwargs):
        content = JSONRenderer().render(data)
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)

class AccountViewSet(viewsets.ModelViewSet):
    lookup_field = 'username'
    queryset = Account.objects.all()
    serializer_class = AccountSerializer

    def get_permissions(self):
        if self.request.method in permissions.SAFE_METHODS:
            return (permissions.AllowAny(),)

        if self.request.method == 'POST':
            return (permissions.AllowAny(),)

        return (permissions.IsAuthenticated(), IsAccountOwner(),)

    def create(self, request):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            Account.objects.create_user(**serializer.validated_data)

            return Response(serializer.validated_data, status=status.HTTP_201_CREATED)
        return JSONResponse(serializer.errors, status=400)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM