gpt4 book ai didi

django - 使用 Django rest 框架生成自定义 token

转载 作者:行者123 更新时间:2023-12-02 02:51:20 24 4
gpt4 key购买 nike

我目前正在为一个 uni 项目构建 API。我在以自定义方式生成身份验证 token 时遇到问题。让我解释一下:我应该在端点中收到一个 POST 请求,其中包含以下内容:

{
"university_id": 1,
"coords":{
"latitude": 0.0,
"longitude": 0.0
}
}

想法是,给定 university_idcoords,后端对其进行验证(检查坐标是否在有效区域内),然后返回一个标记像这样:

{
"token": asdfsagag23214,
}

如您所见,没有涉及登录凭据(也没有涉及客户端应用程序的用户模型),所以我猜我需要创建一个自定义 token 。我查阅了 Django REST Framework 文档,并为我的 token 模型提出了类似这样的内容:

class AuthToken(models.Model):
key = models.CharField(verbose_name='Key', max_length=40, primary_key=True)
created = models.DateTimeField(
verbose_name='Creation date', auto_now_add=True)

class Meta:
verbose_name = 'Token'
verbose_name_plural = 'Tokens'

def save(self, *args, **kwargs):
if not self.key:
self.key = self.generate_key()
return super().save(*args, **kwargs)

def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()

def __str__(self):
return self.key

然后,它是序列化器:

class AuthTokenSerializer(serializers.Serializer):
class Meta:
model = AuthToken
fields = ('key', 'created', )

def to_internal_value(self, data):
university = data.get('university')
coords = data.get('coords')

if not university:
raise serializers.ValidationError({
'university': 'This field is required.'
})
if not coords:
raise serializers.ValidationError({
'coords': 'This field is required.'
})

# coordinate validation goes here

return {
'university': int(university),
'coords': coords
}

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

最后,views.py:

@api_view(['POST'])
def generate_token(request):
if request.method == 'POST':
serializer = AuthTokenSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我不确定我错过了什么,但我想不出我需要做什么才能使这项工作正常进行。现在我正在使用 swagger 对其进行测试,它在任何方面、形状或形式上都不起作用,没有可输入的参数,甚至通过终端使用 cURL 似乎也没有给我预期的结果。

郑重声明,我使用的是 Django 2.1Django Rest framework 3.8.2

我将不胜感激任何帮助,以及对此代码的任何进一步评论(毕竟我还在学习)。我猜我缺少方法,但不确定在哪里。

最佳答案

我一步一步来

首先,您需要为坐标定义序列化程序,因为获取和验证用户输入的标准方法是通过序列化程序。所以:

class Coordinates(serializers.Serializer):
latitude = serializers.FloatField(min_value=-90, max_value=90)
longitude = serializers.FloatField(min_value=-180, max_value=180)

所以我想为字段设置最小值和最大值就可以进行足够的验证。如果您想对该字段进行更多验证,可以使用 field level validation .

其次,对AuthTokenSerializer使用serializer.ModelSerializer,然后在其中添加这个字段:

    coords = Coordinates(write_only=True)

并使其write_only

您也可以使用 PrimaryKeyRelatedField获得这样的大学:

    university = serializers.PrimaryKeyRelatedField(queryset=University.objects.all(), write_only=True)

到目前为止你的序列化器应该是这样的:

class AuthTokenSerializer(serializers.ModelSerializer):
university = serializers.PrimaryKeyRelatedField(queryset=University.objects.all(), write_only=True)
coords = Coordinates(write_only=True)

class Meta:
model = AuthToken
fields = ('key', 'created', 'coords', 'university')

在下一步中,您应该将keycreated 设置为read_only,因为您不想从用户那里获取它们的值输入,您只想在创建 AuthToken 实例后向用户显示它们的值。所以将它们添加到 Meta 类中的 read_only_fields

在下一步中,您应该覆盖序列化器的validate方法,并根据多个字段进行验证(

checks if the coordinates are inside the valid area

)

    def validate(self, attrs):
### the the validation here, something like this
### you can access the selected university instance: attrs['university']

if attrs['coords']['latitude'] < attrs['university']:# blah blah blah, anyway you want to validate
raise serializers.ValidationError({'coords': ['invalid coords']})

return super().validate(attrs)

所以在最后一步中,您应该覆盖 create 方法并弹出模型中没有的字段(大学和坐标):

    def create(self, validated_data):
### your AuthToken does not have this field, you should pop university and coords
### out before creating an instance of Authtoken
validated_data.pop('university')
validated_data.pop('coords')

return super().create(validated_data)

最后你的序列化器会是这样的:

class AuthTokenSerializer(serializers.ModelSerializer):
university = serializers.PrimaryKeyRelatedField(queryset=University.objects.all(), write_only=True)
coords = Coordinates(write_only=True)

class Meta:
model = AuthToken
fields = ('key', 'created', 'coords', 'university')
read_only_fields = ('key', 'created')


def validate(self, attrs):
### the the validation here, something like this
### you can access the selected university instance: attrs['university']

if attrs['coords']['latitude'] < attrs['university']:# blah blah blah, anyway you want to validate
raise serializers.ValidationError({'coords': ['invalid coords']})

return super().validate(attrs)


def create(self, validated_data):
### your AuthToken does not have this field, you should pop university and coords
### out before createing an instance of Authtoken
validated_data.pop('university')
validated_data.pop('coords')

return super().create(validated_data)

关于django - 使用 Django rest 框架生成自定义 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52058541/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com