如何在DRF中使用JWT设置user_id字段

时间:2018-05-14 13:40:37

标签: python django django-rest-framework

我想在创建新预订时使用JWT令牌设置user_id字段并存储在数据库表中。可以有单个或多个预订请求。 每当用户创建预订时,我想在我们的表中存储user_id。目前没有与之相关的外键。它只是一个整数字段。

我可以从JWT获取user_id,但不能在数据库中更新

我知道之前已经问过这个问题我试过上一篇文章的所有答案,但它不适合我。我不知道为什么

model.py

class reservations(models.Model):
  pet_id=models.IntegerField()
  user_id=models.IntegerField(default=0)
  location=models.PositiveSmallIntegerField()
  arrival=models.DateTimeField()
  depature=models.DateTimeField()
  comments=models.TextField(max_length=200)

view.py

class requestReservation(CreateAPIView):
  serializer_class = requestReservationSerailizer
  permission_classes = [IsAuthenticated]

  def create(self, request, *args, **kwargs):   
    serializer = requestReservationSerailizer(data=request.data,context={'user_id': request.user.id}, many=True)

    if not serializer.is_valid(raise_exception=False):
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


    self.perform_create(serializer)
    headers = self.get_success_headers(serializer.data)
    return Response({"message":"Success","status_message":"Reservation Created Successfully"},status=status.HTTP_200_OK)

serializer.py

class requestReservationSerailizer(ModelSerializer):
  user_id = SerializerMethodField('set_user_id')
  class Meta:
    model=reservations
    fields = [
        'pet_id',
        'user_id',
        'location',
        'arrival',
        'depature',                 
        'comments',
    ]

  def set_user_id(self, obj):
    obj.user_id = self.context.get("user_id")
    return obj.user_id

目前只是将user_id存储为0,默认设置为模型。

1 个答案:

答案 0 :(得分:0)

默认情况下,

SerializerMethodField是只读的,在这里快速查看源代码:

def __init__(self, method_name=None, **kwargs):
    self.method_name = method_name
    kwargs['source'] = '*'
    kwargs['read_only'] = True
    super(SerializerMethodField, self).__init__(**kwargs)

假设你想读写这个字段;从序列化器声明中删除SerializerMethodField覆盖;并在您的视图中设置user_id

class requestReservationSerailizer(ModelSerializer):
  class Meta:
    model=reservations
    fields = [
        'pet_id',
        'user_id',
        'location',
        'arrival',
        'depature',                 
        'comments',
    ]


  def create(self, request, *args, **kwargs):
    data = request.data.copy()
    for datum in data:
         datum['user_id'] = request.user.id

    serializer = requestReservationSerailizer(data=data, many=True)

    if not serializer.is_valid(raise_exception=False):
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


    self.perform_create(serializer)
    headers = self.get_success_headers(serializer.data)
    return Response({"message":"Success","status_message":"Reservation Created Successfully"},status=status.HTTP_200_OK)

Ofcourse;如果你不希望你的观点这样做(我在这里同意你的意见),那么在上下文(显式)中传递它或使用self.request.user.id并覆盖validate_user_id < / p>

class requestReservationSerailizer(ModelSerializer):
  class Meta:
    model=reservations
    fields = [
        'pet_id',
        'user_id',
        'location',
        'arrival',
        'depature',                 
        'comments',
    ]

def validate_user_id(self, value):
    user_id = self.context.get('user_id', None)  # Assuming you continue to pass it in context
    if user_id is None:
        # Handle error
    return user_id
    # You can also do this; might raise an AttributeError if the user is not authenticated:
    # return self.request.user.id