Django- रेस्ट-फ्रेमवर्क सीरियलाइज़र में Request.User कैसे प्राप्त करें?


124

मैंने कुछ इस तरह की कोशिश की है, यह काम नहीं करता है।

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post

    def save(self):
        user = self.context['request.user']
        title = self.validated_data['title']
        article = self.validated_data['article']

मुझे अपने Serializer वर्ग से request.user तक पहुंचने में सक्षम होने का एक तरीका चाहिए।


DRF CurrentUserDefaultबिल्कुल F django-rest-framework.org/api-guide/validators/…
andilabs

जवाबों:


231

आप request.userसीधे नहीं पहुँच सकते । आपको अनुरोध ऑब्जेक्ट तक पहुंचने की आवश्यकता है, और फिर उपयोगकर्ता विशेषता प्राप्त करें।

ऐशे ही:

user =  self.context['request'].user

या अधिक सुरक्षित होने के लिए,

user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
    user = request.user

अतिरिक्त संदर्भ पर अधिक यहाँ पढ़ा जा सकता है


1
यह कहता हैNameError: name 'self' is not defined
कोडरेमॉन

बेशक, यह एक वर्ग के संदर्भ में था। आपको सबसे अधिक संभावना है कि एक वर्ग के संदर्भ में नहीं
कार्तिकार

3
मेरे धारावाहिक में, validate()विधि में, self.context एक खाली तानाशाही है। क्यों?
डेविड डी।

14
डेविड - आप शायद इसे बहुत पहले हल कर चुके हैं, लेकिन अगर किसी और के पास यह मुद्दा है, तो यह इसलिए हो सकता है क्योंकि आप अपने धारावाहिक का निर्माण मैन्युअल रूप से कर रहे हैं। मुझे यह समस्या एक नेस्टेड धारावाहिक में एक सामान्य रिश्ते के लिए तुरंत आई। डॉक्स सीरियलाइज़र = नोटरीसेलाइज़र (मान) करने के लिए कहता है लेकिन यह केवल आपके उदाहरण को पारित करेगा, न कि अनुरोध वाले संदर्भ को। आप कंवर को कंस्ट्रक्टर के पास भेज सकते हैं और उसे इसकी आवश्यकता की जानकारी भेज सकते हैं (देखें get_serializer या GenericAPIView इसे कैसे करता है)
जॉन वॉन

2
@JonVaughan कोई भी विवरण कैसे क्रमवार उदाहरण के लिए kwargs पारित करने के लिए ??
तान

74

दरअसल, आपको संदर्भ से परेशान नहीं होना है। इसे करने का एक बेहतर तरीका है:

from rest_framework.fields import CurrentUserDefault

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post

   def save(self):
        user = CurrentUserDefault()  # <= magic!
        title = self.validated_data['title']
        article = self.validated_data['article']

1
यह काम नहीं किया, इसकी वापसी एक अशक्त वस्तु है। user_edit = serializers.CurrentUserDefault ()
एंडरसन मेनेजेस

39

जैसा कि इगोर ने अन्य उत्तर में उल्लेख किया है, उपयोग करेंटयूसेर्डफॉल्ट का उपयोग कर सकते हैं। यदि आप इसके लिए केवल सेव विधि को ओवरराइड नहीं करना चाहते हैं, तो डॉक्टर का उपयोग करें :

from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
    class Meta:
        model = Post

डॉक्टर लिंक अब गलत है।
कोलर-जे

इसी उदाहरण के साथ आधिकारिक डीआरएफ प्रलेखन से लिंक करें django-rest-framework.org/api-guide/serializers/…
Paolo Melchiorre

2

request.userजब आप .save(...)किसी दृश्य के अंदर कॉल कर सकते हैं :

class EventSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.Event
        exclude = ['user']


class EventView(APIView):

    def post(self, request):
        es = EventSerializer(data=request.data)
        if es.is_valid():
            es.save(user=self.request.user)
            return Response(status=status.HTTP_201_CREATED)
        return Response(data=es.errors, status=status.HTTP_400_BAD_REQUEST)

यह मॉडल है:

class Event(models.Model):
    user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    date = models.DateTimeField(default=timezone.now)
    place = models.CharField(max_length=255)

0

आपको अपने धारावाहिक में एक छोटे से संपादन की आवश्यकता है:

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post

    def save(self):
        user = self.context['request'].user
        title = self.validated_data['title']
        article = self.validated_data['article']

यहाँ एक उदाहरण है, मॉडल मिक्सिंग व्यूसेट का उपयोग। में createविधि आप serializer बुलाने की उचित तरीके से पा सकते हैं। get_serializer विधि संदर्भ शब्दकोश को ठीक से भरती है। यदि आपको एक अलग धारावाहिक का उपयोग करने की आवश्यकता है, तो विचार पर परिभाषित किया गया है, updateसंदर्भ शब्दकोश के साथ धारावाहिक को आरंभ करने के तरीके को देखें , जो कि धारावाहिक के लिए अनुरोध ऑब्जेक्ट भी पास करता है।

class SignupViewSet(mixins.UpdateModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):

    http_method_names = ["put", "post"]
    serializer_class = PostSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        kwargs['context'] = self.get_serializer_context()
        serializer = PostSerializer(instance, data=request.data, partial=partial, **kwargs)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)    
        return Response(serializer.data)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.