Django Rest Framework: Display object only for specific choice










1















I've got this serializers:



class PublicProgramSerializer(serializers.ModelSerializer):
class Meta:
model = Program
fields = (
...
'questions'
)

questions = CustomQuestionSerializer(source="custom_questions", many=True)


And:



class CustomQuestionSerializer(serializers.ModelSerializer):

class Meta:
model = CustomQuestion
fields = (
'label',
'type',
'scope'
)


Now the 'scope' is a choice field with 3 options: REGISTRATION, PARTICIPANT, EVENT and I want to serialize only custom questions where the scope is set to REGISTRATION. How can I achieve that?



Thanks for any answer!



Edit: The models:



Program.py



class Program(models.Model):
created = models.DateTimeField(u'Created', auto_now_add=True)
name = models.CharField(u'Program Name', max_length=100)
description = models.TextField(u'Description', help_text=mark_safe(MARKDOWN_HELP_STRING), blank=True, null=True)


etc... Theres nothing really fancy about Program



CustomQuestion.py



class CustomQuestion(models.Model):
class Meta:
order_with_respect_to = 'program'

SCOPE_REGISTRATION = "registration"
SCOPE_PARTICIPANT = "participant"
SCOPE_EVENT = "event"

SCOPE_CHOICES = (
(SCOPE_REGISTRATION, "Registration"),
(SCOPE_PARTICIPANT, "Participant"),
(SCOPE_EVENT, "Event"),
)

program = models.ForeignKey("Program", related_name="custom_questions")
scope = models.CharField(
verbose_name="Scope",
choices=SCOPE_CHOICES,
null=False,
max_length=50
)
description = models.CharField(
verbose_name=u"Description",
null=True, blank=True,
max_length=100
)
label = models.CharField(
verbose_name="Label",
null=False, blank=False,
max_length=80
)


And the Viewset for the Program:



class ProgramList(generics.ListAPIView):
model = Program
permission_classes = (AllowAny,)
serializer_class = PublicProgramSerializer
queryset = Program.objects.exclude(visibility='hidden').filter(is_archived=False)

def get(self, request, *args, **kwargs):
programs = self.get_queryset()
data = self.serializer_class(programs, context='request': request, many=True).data
response = Response(data)
response['Cache-Control'] = 'no-cache'
return response

def get_queryset(self):
scope = self.request.GET.get('scope')
if scope and scope in CustomQuestion.SCOPE_CHOICES:
return Program.objects.filter(participant_questions__scope=scope)
else:
return Program.objects.all()









share|improve this question




























    1















    I've got this serializers:



    class PublicProgramSerializer(serializers.ModelSerializer):
    class Meta:
    model = Program
    fields = (
    ...
    'questions'
    )

    questions = CustomQuestionSerializer(source="custom_questions", many=True)


    And:



    class CustomQuestionSerializer(serializers.ModelSerializer):

    class Meta:
    model = CustomQuestion
    fields = (
    'label',
    'type',
    'scope'
    )


    Now the 'scope' is a choice field with 3 options: REGISTRATION, PARTICIPANT, EVENT and I want to serialize only custom questions where the scope is set to REGISTRATION. How can I achieve that?



    Thanks for any answer!



    Edit: The models:



    Program.py



    class Program(models.Model):
    created = models.DateTimeField(u'Created', auto_now_add=True)
    name = models.CharField(u'Program Name', max_length=100)
    description = models.TextField(u'Description', help_text=mark_safe(MARKDOWN_HELP_STRING), blank=True, null=True)


    etc... Theres nothing really fancy about Program



    CustomQuestion.py



    class CustomQuestion(models.Model):
    class Meta:
    order_with_respect_to = 'program'

    SCOPE_REGISTRATION = "registration"
    SCOPE_PARTICIPANT = "participant"
    SCOPE_EVENT = "event"

    SCOPE_CHOICES = (
    (SCOPE_REGISTRATION, "Registration"),
    (SCOPE_PARTICIPANT, "Participant"),
    (SCOPE_EVENT, "Event"),
    )

    program = models.ForeignKey("Program", related_name="custom_questions")
    scope = models.CharField(
    verbose_name="Scope",
    choices=SCOPE_CHOICES,
    null=False,
    max_length=50
    )
    description = models.CharField(
    verbose_name=u"Description",
    null=True, blank=True,
    max_length=100
    )
    label = models.CharField(
    verbose_name="Label",
    null=False, blank=False,
    max_length=80
    )


    And the Viewset for the Program:



    class ProgramList(generics.ListAPIView):
    model = Program
    permission_classes = (AllowAny,)
    serializer_class = PublicProgramSerializer
    queryset = Program.objects.exclude(visibility='hidden').filter(is_archived=False)

    def get(self, request, *args, **kwargs):
    programs = self.get_queryset()
    data = self.serializer_class(programs, context='request': request, many=True).data
    response = Response(data)
    response['Cache-Control'] = 'no-cache'
    return response

    def get_queryset(self):
    scope = self.request.GET.get('scope')
    if scope and scope in CustomQuestion.SCOPE_CHOICES:
    return Program.objects.filter(participant_questions__scope=scope)
    else:
    return Program.objects.all()









    share|improve this question


























      1












      1








      1


      0






      I've got this serializers:



      class PublicProgramSerializer(serializers.ModelSerializer):
      class Meta:
      model = Program
      fields = (
      ...
      'questions'
      )

      questions = CustomQuestionSerializer(source="custom_questions", many=True)


      And:



      class CustomQuestionSerializer(serializers.ModelSerializer):

      class Meta:
      model = CustomQuestion
      fields = (
      'label',
      'type',
      'scope'
      )


      Now the 'scope' is a choice field with 3 options: REGISTRATION, PARTICIPANT, EVENT and I want to serialize only custom questions where the scope is set to REGISTRATION. How can I achieve that?



      Thanks for any answer!



      Edit: The models:



      Program.py



      class Program(models.Model):
      created = models.DateTimeField(u'Created', auto_now_add=True)
      name = models.CharField(u'Program Name', max_length=100)
      description = models.TextField(u'Description', help_text=mark_safe(MARKDOWN_HELP_STRING), blank=True, null=True)


      etc... Theres nothing really fancy about Program



      CustomQuestion.py



      class CustomQuestion(models.Model):
      class Meta:
      order_with_respect_to = 'program'

      SCOPE_REGISTRATION = "registration"
      SCOPE_PARTICIPANT = "participant"
      SCOPE_EVENT = "event"

      SCOPE_CHOICES = (
      (SCOPE_REGISTRATION, "Registration"),
      (SCOPE_PARTICIPANT, "Participant"),
      (SCOPE_EVENT, "Event"),
      )

      program = models.ForeignKey("Program", related_name="custom_questions")
      scope = models.CharField(
      verbose_name="Scope",
      choices=SCOPE_CHOICES,
      null=False,
      max_length=50
      )
      description = models.CharField(
      verbose_name=u"Description",
      null=True, blank=True,
      max_length=100
      )
      label = models.CharField(
      verbose_name="Label",
      null=False, blank=False,
      max_length=80
      )


      And the Viewset for the Program:



      class ProgramList(generics.ListAPIView):
      model = Program
      permission_classes = (AllowAny,)
      serializer_class = PublicProgramSerializer
      queryset = Program.objects.exclude(visibility='hidden').filter(is_archived=False)

      def get(self, request, *args, **kwargs):
      programs = self.get_queryset()
      data = self.serializer_class(programs, context='request': request, many=True).data
      response = Response(data)
      response['Cache-Control'] = 'no-cache'
      return response

      def get_queryset(self):
      scope = self.request.GET.get('scope')
      if scope and scope in CustomQuestion.SCOPE_CHOICES:
      return Program.objects.filter(participant_questions__scope=scope)
      else:
      return Program.objects.all()









      share|improve this question
















      I've got this serializers:



      class PublicProgramSerializer(serializers.ModelSerializer):
      class Meta:
      model = Program
      fields = (
      ...
      'questions'
      )

      questions = CustomQuestionSerializer(source="custom_questions", many=True)


      And:



      class CustomQuestionSerializer(serializers.ModelSerializer):

      class Meta:
      model = CustomQuestion
      fields = (
      'label',
      'type',
      'scope'
      )


      Now the 'scope' is a choice field with 3 options: REGISTRATION, PARTICIPANT, EVENT and I want to serialize only custom questions where the scope is set to REGISTRATION. How can I achieve that?



      Thanks for any answer!



      Edit: The models:



      Program.py



      class Program(models.Model):
      created = models.DateTimeField(u'Created', auto_now_add=True)
      name = models.CharField(u'Program Name', max_length=100)
      description = models.TextField(u'Description', help_text=mark_safe(MARKDOWN_HELP_STRING), blank=True, null=True)


      etc... Theres nothing really fancy about Program



      CustomQuestion.py



      class CustomQuestion(models.Model):
      class Meta:
      order_with_respect_to = 'program'

      SCOPE_REGISTRATION = "registration"
      SCOPE_PARTICIPANT = "participant"
      SCOPE_EVENT = "event"

      SCOPE_CHOICES = (
      (SCOPE_REGISTRATION, "Registration"),
      (SCOPE_PARTICIPANT, "Participant"),
      (SCOPE_EVENT, "Event"),
      )

      program = models.ForeignKey("Program", related_name="custom_questions")
      scope = models.CharField(
      verbose_name="Scope",
      choices=SCOPE_CHOICES,
      null=False,
      max_length=50
      )
      description = models.CharField(
      verbose_name=u"Description",
      null=True, blank=True,
      max_length=100
      )
      label = models.CharField(
      verbose_name="Label",
      null=False, blank=False,
      max_length=80
      )


      And the Viewset for the Program:



      class ProgramList(generics.ListAPIView):
      model = Program
      permission_classes = (AllowAny,)
      serializer_class = PublicProgramSerializer
      queryset = Program.objects.exclude(visibility='hidden').filter(is_archived=False)

      def get(self, request, *args, **kwargs):
      programs = self.get_queryset()
      data = self.serializer_class(programs, context='request': request, many=True).data
      response = Response(data)
      response['Cache-Control'] = 'no-cache'
      return response

      def get_queryset(self):
      scope = self.request.GET.get('scope')
      if scope and scope in CustomQuestion.SCOPE_CHOICES:
      return Program.objects.filter(participant_questions__scope=scope)
      else:
      return Program.objects.all()






      python django django-rest-framework






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 15 '18 at 11:52







      NakedPython

















      asked Nov 15 '18 at 9:55









      NakedPythonNakedPython

      2261212




      2261212






















          2 Answers
          2






          active

          oldest

          votes


















          2














          Create a method called "get_queryset" in your viewset like this



          class ProgramViewSet(viewsets.ViewSet):
          serializer_class = ProgramSerializer

          def get_queryset(self):
          scope = self.request.GET.get('scope')
          if scope and scope in CustomQuestion.SCOPE_CHOICE:
          return Program.objects.filter(questions__scope=scope)
          else
          return Program.objects.all()

          def list(self, request):
          paginator = LimitOffsetPagination()
          if request.GET.get('limit'):
          page = paginator.paginate_queryset(self.get_queryset(), request)
          serializer = self.serializer_class(page, many=True)
          if page is not None:
          return paginator.get_paginated_response(serializer.data)
          else:
          serializer = self.serializer_class(self.get_queryset(), many=True)
          return response.Response(serializer.data)





          share|improve this answer

























          • If I try using this the scope variable returns None for me sadly

            – NakedPython
            Nov 15 '18 at 10:49











          • How did you call this serializer?

            – a_k_v
            Nov 15 '18 at 11:03











          • @a_k_v answer updated with pagination example

            – Bast
            Nov 15 '18 at 11:27












          • @NikolaiNowolodski Can you add your models to the question? this solution should work with a FK Field

            – Bast
            Nov 15 '18 at 11:30











          • @Bast I've added my models and also the viewset I'm using

            – NakedPython
            Nov 15 '18 at 11:52


















          0














          Well I have found a solution that works for me pretty well:



          I didn't know that you can use a custom method as the source in the Serializer Method like:



          questions = CustomQuestionSerializer(source="get_participant_questions", many=True)


          So I just created the get_participant_questions method in my program.py, where I filtered for those exact questions:



          def get_participant_questions(self):
          return self.custom_questions.filter(scope=CustomQuestion.SCOPE_PARTICIPANT)


          and et voila my API showed me exactly what I wanted.



          Thanks a lot @Bast, your answer helped me find this way :)






          share|improve this answer






















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53316727%2fdjango-rest-framework-display-object-only-for-specific-choice%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            Create a method called "get_queryset" in your viewset like this



            class ProgramViewSet(viewsets.ViewSet):
            serializer_class = ProgramSerializer

            def get_queryset(self):
            scope = self.request.GET.get('scope')
            if scope and scope in CustomQuestion.SCOPE_CHOICE:
            return Program.objects.filter(questions__scope=scope)
            else
            return Program.objects.all()

            def list(self, request):
            paginator = LimitOffsetPagination()
            if request.GET.get('limit'):
            page = paginator.paginate_queryset(self.get_queryset(), request)
            serializer = self.serializer_class(page, many=True)
            if page is not None:
            return paginator.get_paginated_response(serializer.data)
            else:
            serializer = self.serializer_class(self.get_queryset(), many=True)
            return response.Response(serializer.data)





            share|improve this answer

























            • If I try using this the scope variable returns None for me sadly

              – NakedPython
              Nov 15 '18 at 10:49











            • How did you call this serializer?

              – a_k_v
              Nov 15 '18 at 11:03











            • @a_k_v answer updated with pagination example

              – Bast
              Nov 15 '18 at 11:27












            • @NikolaiNowolodski Can you add your models to the question? this solution should work with a FK Field

              – Bast
              Nov 15 '18 at 11:30











            • @Bast I've added my models and also the viewset I'm using

              – NakedPython
              Nov 15 '18 at 11:52















            2














            Create a method called "get_queryset" in your viewset like this



            class ProgramViewSet(viewsets.ViewSet):
            serializer_class = ProgramSerializer

            def get_queryset(self):
            scope = self.request.GET.get('scope')
            if scope and scope in CustomQuestion.SCOPE_CHOICE:
            return Program.objects.filter(questions__scope=scope)
            else
            return Program.objects.all()

            def list(self, request):
            paginator = LimitOffsetPagination()
            if request.GET.get('limit'):
            page = paginator.paginate_queryset(self.get_queryset(), request)
            serializer = self.serializer_class(page, many=True)
            if page is not None:
            return paginator.get_paginated_response(serializer.data)
            else:
            serializer = self.serializer_class(self.get_queryset(), many=True)
            return response.Response(serializer.data)





            share|improve this answer

























            • If I try using this the scope variable returns None for me sadly

              – NakedPython
              Nov 15 '18 at 10:49











            • How did you call this serializer?

              – a_k_v
              Nov 15 '18 at 11:03











            • @a_k_v answer updated with pagination example

              – Bast
              Nov 15 '18 at 11:27












            • @NikolaiNowolodski Can you add your models to the question? this solution should work with a FK Field

              – Bast
              Nov 15 '18 at 11:30











            • @Bast I've added my models and also the viewset I'm using

              – NakedPython
              Nov 15 '18 at 11:52













            2












            2








            2







            Create a method called "get_queryset" in your viewset like this



            class ProgramViewSet(viewsets.ViewSet):
            serializer_class = ProgramSerializer

            def get_queryset(self):
            scope = self.request.GET.get('scope')
            if scope and scope in CustomQuestion.SCOPE_CHOICE:
            return Program.objects.filter(questions__scope=scope)
            else
            return Program.objects.all()

            def list(self, request):
            paginator = LimitOffsetPagination()
            if request.GET.get('limit'):
            page = paginator.paginate_queryset(self.get_queryset(), request)
            serializer = self.serializer_class(page, many=True)
            if page is not None:
            return paginator.get_paginated_response(serializer.data)
            else:
            serializer = self.serializer_class(self.get_queryset(), many=True)
            return response.Response(serializer.data)





            share|improve this answer















            Create a method called "get_queryset" in your viewset like this



            class ProgramViewSet(viewsets.ViewSet):
            serializer_class = ProgramSerializer

            def get_queryset(self):
            scope = self.request.GET.get('scope')
            if scope and scope in CustomQuestion.SCOPE_CHOICE:
            return Program.objects.filter(questions__scope=scope)
            else
            return Program.objects.all()

            def list(self, request):
            paginator = LimitOffsetPagination()
            if request.GET.get('limit'):
            page = paginator.paginate_queryset(self.get_queryset(), request)
            serializer = self.serializer_class(page, many=True)
            if page is not None:
            return paginator.get_paginated_response(serializer.data)
            else:
            serializer = self.serializer_class(self.get_queryset(), many=True)
            return response.Response(serializer.data)






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 15 '18 at 13:35

























            answered Nov 15 '18 at 10:07









            BastBast

            374111




            374111












            • If I try using this the scope variable returns None for me sadly

              – NakedPython
              Nov 15 '18 at 10:49











            • How did you call this serializer?

              – a_k_v
              Nov 15 '18 at 11:03











            • @a_k_v answer updated with pagination example

              – Bast
              Nov 15 '18 at 11:27












            • @NikolaiNowolodski Can you add your models to the question? this solution should work with a FK Field

              – Bast
              Nov 15 '18 at 11:30











            • @Bast I've added my models and also the viewset I'm using

              – NakedPython
              Nov 15 '18 at 11:52

















            • If I try using this the scope variable returns None for me sadly

              – NakedPython
              Nov 15 '18 at 10:49











            • How did you call this serializer?

              – a_k_v
              Nov 15 '18 at 11:03











            • @a_k_v answer updated with pagination example

              – Bast
              Nov 15 '18 at 11:27












            • @NikolaiNowolodski Can you add your models to the question? this solution should work with a FK Field

              – Bast
              Nov 15 '18 at 11:30











            • @Bast I've added my models and also the viewset I'm using

              – NakedPython
              Nov 15 '18 at 11:52
















            If I try using this the scope variable returns None for me sadly

            – NakedPython
            Nov 15 '18 at 10:49





            If I try using this the scope variable returns None for me sadly

            – NakedPython
            Nov 15 '18 at 10:49













            How did you call this serializer?

            – a_k_v
            Nov 15 '18 at 11:03





            How did you call this serializer?

            – a_k_v
            Nov 15 '18 at 11:03













            @a_k_v answer updated with pagination example

            – Bast
            Nov 15 '18 at 11:27






            @a_k_v answer updated with pagination example

            – Bast
            Nov 15 '18 at 11:27














            @NikolaiNowolodski Can you add your models to the question? this solution should work with a FK Field

            – Bast
            Nov 15 '18 at 11:30





            @NikolaiNowolodski Can you add your models to the question? this solution should work with a FK Field

            – Bast
            Nov 15 '18 at 11:30













            @Bast I've added my models and also the viewset I'm using

            – NakedPython
            Nov 15 '18 at 11:52





            @Bast I've added my models and also the viewset I'm using

            – NakedPython
            Nov 15 '18 at 11:52













            0














            Well I have found a solution that works for me pretty well:



            I didn't know that you can use a custom method as the source in the Serializer Method like:



            questions = CustomQuestionSerializer(source="get_participant_questions", many=True)


            So I just created the get_participant_questions method in my program.py, where I filtered for those exact questions:



            def get_participant_questions(self):
            return self.custom_questions.filter(scope=CustomQuestion.SCOPE_PARTICIPANT)


            and et voila my API showed me exactly what I wanted.



            Thanks a lot @Bast, your answer helped me find this way :)






            share|improve this answer



























              0














              Well I have found a solution that works for me pretty well:



              I didn't know that you can use a custom method as the source in the Serializer Method like:



              questions = CustomQuestionSerializer(source="get_participant_questions", many=True)


              So I just created the get_participant_questions method in my program.py, where I filtered for those exact questions:



              def get_participant_questions(self):
              return self.custom_questions.filter(scope=CustomQuestion.SCOPE_PARTICIPANT)


              and et voila my API showed me exactly what I wanted.



              Thanks a lot @Bast, your answer helped me find this way :)






              share|improve this answer

























                0












                0








                0







                Well I have found a solution that works for me pretty well:



                I didn't know that you can use a custom method as the source in the Serializer Method like:



                questions = CustomQuestionSerializer(source="get_participant_questions", many=True)


                So I just created the get_participant_questions method in my program.py, where I filtered for those exact questions:



                def get_participant_questions(self):
                return self.custom_questions.filter(scope=CustomQuestion.SCOPE_PARTICIPANT)


                and et voila my API showed me exactly what I wanted.



                Thanks a lot @Bast, your answer helped me find this way :)






                share|improve this answer













                Well I have found a solution that works for me pretty well:



                I didn't know that you can use a custom method as the source in the Serializer Method like:



                questions = CustomQuestionSerializer(source="get_participant_questions", many=True)


                So I just created the get_participant_questions method in my program.py, where I filtered for those exact questions:



                def get_participant_questions(self):
                return self.custom_questions.filter(scope=CustomQuestion.SCOPE_PARTICIPANT)


                and et voila my API showed me exactly what I wanted.



                Thanks a lot @Bast, your answer helped me find this way :)







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 15 '18 at 14:43









                NakedPythonNakedPython

                2261212




                2261212



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53316727%2fdjango-rest-framework-display-object-only-for-specific-choice%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Barbados

                    How to read a connectionString WITH PROVIDER in .NET Core?

                    Node.js Script on GitHub Pages or Amazon S3