Search code examples
djangodjango-modelsdjango-rest-frameworksqlalchemyorm

Getting the Django ORM auth_user.id data using serializer


I have a model of SQLAlchemy. Here is my models.py:

class PlaceInfoModel(Base):
    __tablename__ = 'place_info'

    id = Column(Integer, primary_key=True, autoincrement=True)
    owner_id = Column(Integer,nullable=False)  
    name = Column(String(60))
    address = Column(String(300))
    rating = Column(Float)
    type = Column(String(20))
    image = Column(String)

serializer.py:

from .models import PlaceInfoModel, sessionmaker,engine
from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework.fields import CurrentUserDefault


class PlaceInfoSerializer(serializers.Serializer):
    name = serializers.CharField()
    address = serializers.CharField()
    rating = serializers.FloatField()
    image = serializers.CharField(required=False)
    owner_id = serializers.IntegerField() # i want to auto update it with auth_user.id on POST request
    
    
        

This is my views.py:

class PlaceViewSet(ViewSet):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticatedOrReadOnly, IsPermittedForAction]
    ordering_fields = ['id', 'name', 'rating', 'address']

    
    def create(self, request):
        serializer = PlaceInfoSerializer(data=request.data)
        print(request.user.id)
        if serializer.is_valid():
            Session = sessionmaker(bind=engine)
            session = Session()
            place = PlaceInfoModel(**serializer.validated_data)
            session.add(place)
            session.commit()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

I want to populate my owner_id in serializers.py somehow from SimpleJWT authentication. I tried to do it with CurrentUserDefault() and failed.


Solution

  • You can make the owner_id read-only:

    class PlaceInfoSerializer(serializers.Serializer):
        name = serializers.CharField()
        address = serializers.CharField()
        rating = serializers.FloatField()
        image = serializers.CharField(required=False)
        owner_id = serializers.IntegerField(read_only=True)

    and then pass it manually in the serializer:

    class PlaceViewSet(ViewSet):
        authentication_classes = [JWTAuthentication]
        permission_classes = [IsAuthenticatedOrReadOnly, IsPermittedForAction]
        ordering_fields = ['id', 'name', 'rating', 'address']
    
        def create(self, request):
            serializer = PlaceInfoSerializer(data=request.data)
            print(request.user.id)
            if serializer.is_valid():
                Session = sessionmaker(bind=engine)
                session = Session()
                place = PlaceInfoModel(
                    **serializer.validated_data, onwer_id=request.user.id
                )
                session.add(place)
                session.commit()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    That being said, I don't really see why you use Django if you don't use the ORM or model. Django is mainly centered around models: it can define serializers, forms, etc. all based on a model. So without models, it falls back on implementing a lot of boilerplate code, making Django not ideal.