Django rest framework add more data when serialize many object












0















I would like to add an additional field for user's details. But it has to use another value outside of database fields.
For more clearly like this



model:



class User(models.Model):
id= models.AutoField(primary_key=True)
last_name= models.CharField(max_length=20)
first_name=models.CharField(max_length=20)
role_id = models.IntegerField()


serializer:



class UserSerializer(serializers.ModelSerializer):
display_summary = serializers.SerializerMethodField()
login_user_id = serializers.IntegerField(required=False)

class Meta:
model = User
fields = ("id","last_name","first_name", "display_summary", "login_user_id")

def get_display_summary(self, obj):
login_id = self.validated_data.get('login_user_id', None)
login_user = User.objects.filter(pk=login_id).first()
if obj.role_id==2 and login_user.role_id==1:
return 1

return 0


So in my views, when getting just one user, it's all ok:



@api_view(['GET'])
@login_required
def get_user(request, login_user, user_id):
serializer = UserSerializer(User.objects.get(pk=user_id), data={'login_user_id': login_user.id})
if serializer.is_valid():
result = serializer.data
return Response(result, status=status.HTTP_200_OK)

#result:
#{
# "id": 2,
# "last_name": "V",
# "first_name": "Lich",
# "role_id": 2,
# "display_summary": 1
#}


But when I need to return a list, how can I add additional data (login_user_id)?
This is not working:



users = User.objects.filter(last_name__icontains='v')
result_serializer = UserSerializer(users, data={'login_user_id': login_user.id}, many=True)
return result_serializer.data


The error occur say that it's looking for a list, not a dict for inputted param.










share|improve this question























  • users is a list and data is a dictionary, why it should work correct?

    – Bear Brown
    Nov 19 '18 at 7:57











  • Thanks for having attention to my answer. Maybe my English is too ugly, I meant to ask how can I get a list of users, with each one running through UserSerializer for adding custom field that use outside data from database query object?

    – LucVH
    Nov 19 '18 at 8:04











  • As you want to work with list, you should pass list of dict to data parameters. Example (just a mock data): result_serializer = UserSerializer(users, data=[{'login_user_id': login_id_1}, {'login_user_id': login_id_2}], many=True)

    – Hai Lang
    Nov 19 '18 at 11:59











  • @LucVH do you wish to add the same login_user_id value to each user in the list? Or should each user get a different login_user_id value?

    – Will Keeling
    Nov 19 '18 at 13:59













  • @WillKeeling: I wish to add the same login_user_id value to each user in the list

    – LucVH
    Nov 20 '18 at 7:30
















0















I would like to add an additional field for user's details. But it has to use another value outside of database fields.
For more clearly like this



model:



class User(models.Model):
id= models.AutoField(primary_key=True)
last_name= models.CharField(max_length=20)
first_name=models.CharField(max_length=20)
role_id = models.IntegerField()


serializer:



class UserSerializer(serializers.ModelSerializer):
display_summary = serializers.SerializerMethodField()
login_user_id = serializers.IntegerField(required=False)

class Meta:
model = User
fields = ("id","last_name","first_name", "display_summary", "login_user_id")

def get_display_summary(self, obj):
login_id = self.validated_data.get('login_user_id', None)
login_user = User.objects.filter(pk=login_id).first()
if obj.role_id==2 and login_user.role_id==1:
return 1

return 0


So in my views, when getting just one user, it's all ok:



@api_view(['GET'])
@login_required
def get_user(request, login_user, user_id):
serializer = UserSerializer(User.objects.get(pk=user_id), data={'login_user_id': login_user.id})
if serializer.is_valid():
result = serializer.data
return Response(result, status=status.HTTP_200_OK)

#result:
#{
# "id": 2,
# "last_name": "V",
# "first_name": "Lich",
# "role_id": 2,
# "display_summary": 1
#}


But when I need to return a list, how can I add additional data (login_user_id)?
This is not working:



users = User.objects.filter(last_name__icontains='v')
result_serializer = UserSerializer(users, data={'login_user_id': login_user.id}, many=True)
return result_serializer.data


The error occur say that it's looking for a list, not a dict for inputted param.










share|improve this question























  • users is a list and data is a dictionary, why it should work correct?

    – Bear Brown
    Nov 19 '18 at 7:57











  • Thanks for having attention to my answer. Maybe my English is too ugly, I meant to ask how can I get a list of users, with each one running through UserSerializer for adding custom field that use outside data from database query object?

    – LucVH
    Nov 19 '18 at 8:04











  • As you want to work with list, you should pass list of dict to data parameters. Example (just a mock data): result_serializer = UserSerializer(users, data=[{'login_user_id': login_id_1}, {'login_user_id': login_id_2}], many=True)

    – Hai Lang
    Nov 19 '18 at 11:59











  • @LucVH do you wish to add the same login_user_id value to each user in the list? Or should each user get a different login_user_id value?

    – Will Keeling
    Nov 19 '18 at 13:59













  • @WillKeeling: I wish to add the same login_user_id value to each user in the list

    – LucVH
    Nov 20 '18 at 7:30














0












0








0








I would like to add an additional field for user's details. But it has to use another value outside of database fields.
For more clearly like this



model:



class User(models.Model):
id= models.AutoField(primary_key=True)
last_name= models.CharField(max_length=20)
first_name=models.CharField(max_length=20)
role_id = models.IntegerField()


serializer:



class UserSerializer(serializers.ModelSerializer):
display_summary = serializers.SerializerMethodField()
login_user_id = serializers.IntegerField(required=False)

class Meta:
model = User
fields = ("id","last_name","first_name", "display_summary", "login_user_id")

def get_display_summary(self, obj):
login_id = self.validated_data.get('login_user_id', None)
login_user = User.objects.filter(pk=login_id).first()
if obj.role_id==2 and login_user.role_id==1:
return 1

return 0


So in my views, when getting just one user, it's all ok:



@api_view(['GET'])
@login_required
def get_user(request, login_user, user_id):
serializer = UserSerializer(User.objects.get(pk=user_id), data={'login_user_id': login_user.id})
if serializer.is_valid():
result = serializer.data
return Response(result, status=status.HTTP_200_OK)

#result:
#{
# "id": 2,
# "last_name": "V",
# "first_name": "Lich",
# "role_id": 2,
# "display_summary": 1
#}


But when I need to return a list, how can I add additional data (login_user_id)?
This is not working:



users = User.objects.filter(last_name__icontains='v')
result_serializer = UserSerializer(users, data={'login_user_id': login_user.id}, many=True)
return result_serializer.data


The error occur say that it's looking for a list, not a dict for inputted param.










share|improve this question














I would like to add an additional field for user's details. But it has to use another value outside of database fields.
For more clearly like this



model:



class User(models.Model):
id= models.AutoField(primary_key=True)
last_name= models.CharField(max_length=20)
first_name=models.CharField(max_length=20)
role_id = models.IntegerField()


serializer:



class UserSerializer(serializers.ModelSerializer):
display_summary = serializers.SerializerMethodField()
login_user_id = serializers.IntegerField(required=False)

class Meta:
model = User
fields = ("id","last_name","first_name", "display_summary", "login_user_id")

def get_display_summary(self, obj):
login_id = self.validated_data.get('login_user_id', None)
login_user = User.objects.filter(pk=login_id).first()
if obj.role_id==2 and login_user.role_id==1:
return 1

return 0


So in my views, when getting just one user, it's all ok:



@api_view(['GET'])
@login_required
def get_user(request, login_user, user_id):
serializer = UserSerializer(User.objects.get(pk=user_id), data={'login_user_id': login_user.id})
if serializer.is_valid():
result = serializer.data
return Response(result, status=status.HTTP_200_OK)

#result:
#{
# "id": 2,
# "last_name": "V",
# "first_name": "Lich",
# "role_id": 2,
# "display_summary": 1
#}


But when I need to return a list, how can I add additional data (login_user_id)?
This is not working:



users = User.objects.filter(last_name__icontains='v')
result_serializer = UserSerializer(users, data={'login_user_id': login_user.id}, many=True)
return result_serializer.data


The error occur say that it's looking for a list, not a dict for inputted param.







python django django-rest-framework serializer






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 '18 at 7:49









LucVHLucVH

112114




112114













  • users is a list and data is a dictionary, why it should work correct?

    – Bear Brown
    Nov 19 '18 at 7:57











  • Thanks for having attention to my answer. Maybe my English is too ugly, I meant to ask how can I get a list of users, with each one running through UserSerializer for adding custom field that use outside data from database query object?

    – LucVH
    Nov 19 '18 at 8:04











  • As you want to work with list, you should pass list of dict to data parameters. Example (just a mock data): result_serializer = UserSerializer(users, data=[{'login_user_id': login_id_1}, {'login_user_id': login_id_2}], many=True)

    – Hai Lang
    Nov 19 '18 at 11:59











  • @LucVH do you wish to add the same login_user_id value to each user in the list? Or should each user get a different login_user_id value?

    – Will Keeling
    Nov 19 '18 at 13:59













  • @WillKeeling: I wish to add the same login_user_id value to each user in the list

    – LucVH
    Nov 20 '18 at 7:30



















  • users is a list and data is a dictionary, why it should work correct?

    – Bear Brown
    Nov 19 '18 at 7:57











  • Thanks for having attention to my answer. Maybe my English is too ugly, I meant to ask how can I get a list of users, with each one running through UserSerializer for adding custom field that use outside data from database query object?

    – LucVH
    Nov 19 '18 at 8:04











  • As you want to work with list, you should pass list of dict to data parameters. Example (just a mock data): result_serializer = UserSerializer(users, data=[{'login_user_id': login_id_1}, {'login_user_id': login_id_2}], many=True)

    – Hai Lang
    Nov 19 '18 at 11:59











  • @LucVH do you wish to add the same login_user_id value to each user in the list? Or should each user get a different login_user_id value?

    – Will Keeling
    Nov 19 '18 at 13:59













  • @WillKeeling: I wish to add the same login_user_id value to each user in the list

    – LucVH
    Nov 20 '18 at 7:30

















users is a list and data is a dictionary, why it should work correct?

– Bear Brown
Nov 19 '18 at 7:57





users is a list and data is a dictionary, why it should work correct?

– Bear Brown
Nov 19 '18 at 7:57













Thanks for having attention to my answer. Maybe my English is too ugly, I meant to ask how can I get a list of users, with each one running through UserSerializer for adding custom field that use outside data from database query object?

– LucVH
Nov 19 '18 at 8:04





Thanks for having attention to my answer. Maybe my English is too ugly, I meant to ask how can I get a list of users, with each one running through UserSerializer for adding custom field that use outside data from database query object?

– LucVH
Nov 19 '18 at 8:04













As you want to work with list, you should pass list of dict to data parameters. Example (just a mock data): result_serializer = UserSerializer(users, data=[{'login_user_id': login_id_1}, {'login_user_id': login_id_2}], many=True)

– Hai Lang
Nov 19 '18 at 11:59





As you want to work with list, you should pass list of dict to data parameters. Example (just a mock data): result_serializer = UserSerializer(users, data=[{'login_user_id': login_id_1}, {'login_user_id': login_id_2}], many=True)

– Hai Lang
Nov 19 '18 at 11:59













@LucVH do you wish to add the same login_user_id value to each user in the list? Or should each user get a different login_user_id value?

– Will Keeling
Nov 19 '18 at 13:59







@LucVH do you wish to add the same login_user_id value to each user in the list? Or should each user get a different login_user_id value?

– Will Keeling
Nov 19 '18 at 13:59















@WillKeeling: I wish to add the same login_user_id value to each user in the list

– LucVH
Nov 20 '18 at 7:30





@WillKeeling: I wish to add the same login_user_id value to each user in the list

– LucVH
Nov 20 '18 at 7:30












1 Answer
1






active

oldest

votes


















0














Based on @Hai Lang 's idea, I made a new namedtuple to add more info. Something like this:



Serializer:
No use ModelSerializer, use normal Serializer with field I would like to show on this view



class UserSummarySerializer(serializers.Serializer):
user_id = serializers.SerializerMethodField()
last_name = serializers.SerializerMethodField()
first_name = serializers.SerializerMethodField()
display_summary = serializers.SerializerMethodField()

def validate(self, data):
#some validation if needed
return data
def get_user_id(self, obj):
return obj.user.user_id
def get_last_name(self, obj):
return obj.user.last_name
def get_first_name(self, obj):
return obj.user.first_name
def get_display_summary(self, obj):
login_user = obj.login_user
if obj.role_id==2 and login_user.role_id==1:
return 1

return 0


then in my views:



userSummary = namedtuple('userSummary ', ('user', 'login_user'))
users = User.objects.filter(last_name__icontains='v')
objs = [userSummary(u, login_user) for u in users]
result_serializer = UserSerializer(objs, many=True)
return result_serializer.data





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%2f53370350%2fdjango-rest-framework-add-more-data-when-serialize-many-object%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Based on @Hai Lang 's idea, I made a new namedtuple to add more info. Something like this:



    Serializer:
    No use ModelSerializer, use normal Serializer with field I would like to show on this view



    class UserSummarySerializer(serializers.Serializer):
    user_id = serializers.SerializerMethodField()
    last_name = serializers.SerializerMethodField()
    first_name = serializers.SerializerMethodField()
    display_summary = serializers.SerializerMethodField()

    def validate(self, data):
    #some validation if needed
    return data
    def get_user_id(self, obj):
    return obj.user.user_id
    def get_last_name(self, obj):
    return obj.user.last_name
    def get_first_name(self, obj):
    return obj.user.first_name
    def get_display_summary(self, obj):
    login_user = obj.login_user
    if obj.role_id==2 and login_user.role_id==1:
    return 1

    return 0


    then in my views:



    userSummary = namedtuple('userSummary ', ('user', 'login_user'))
    users = User.objects.filter(last_name__icontains='v')
    objs = [userSummary(u, login_user) for u in users]
    result_serializer = UserSerializer(objs, many=True)
    return result_serializer.data





    share|improve this answer




























      0














      Based on @Hai Lang 's idea, I made a new namedtuple to add more info. Something like this:



      Serializer:
      No use ModelSerializer, use normal Serializer with field I would like to show on this view



      class UserSummarySerializer(serializers.Serializer):
      user_id = serializers.SerializerMethodField()
      last_name = serializers.SerializerMethodField()
      first_name = serializers.SerializerMethodField()
      display_summary = serializers.SerializerMethodField()

      def validate(self, data):
      #some validation if needed
      return data
      def get_user_id(self, obj):
      return obj.user.user_id
      def get_last_name(self, obj):
      return obj.user.last_name
      def get_first_name(self, obj):
      return obj.user.first_name
      def get_display_summary(self, obj):
      login_user = obj.login_user
      if obj.role_id==2 and login_user.role_id==1:
      return 1

      return 0


      then in my views:



      userSummary = namedtuple('userSummary ', ('user', 'login_user'))
      users = User.objects.filter(last_name__icontains='v')
      objs = [userSummary(u, login_user) for u in users]
      result_serializer = UserSerializer(objs, many=True)
      return result_serializer.data





      share|improve this answer


























        0












        0








        0







        Based on @Hai Lang 's idea, I made a new namedtuple to add more info. Something like this:



        Serializer:
        No use ModelSerializer, use normal Serializer with field I would like to show on this view



        class UserSummarySerializer(serializers.Serializer):
        user_id = serializers.SerializerMethodField()
        last_name = serializers.SerializerMethodField()
        first_name = serializers.SerializerMethodField()
        display_summary = serializers.SerializerMethodField()

        def validate(self, data):
        #some validation if needed
        return data
        def get_user_id(self, obj):
        return obj.user.user_id
        def get_last_name(self, obj):
        return obj.user.last_name
        def get_first_name(self, obj):
        return obj.user.first_name
        def get_display_summary(self, obj):
        login_user = obj.login_user
        if obj.role_id==2 and login_user.role_id==1:
        return 1

        return 0


        then in my views:



        userSummary = namedtuple('userSummary ', ('user', 'login_user'))
        users = User.objects.filter(last_name__icontains='v')
        objs = [userSummary(u, login_user) for u in users]
        result_serializer = UserSerializer(objs, many=True)
        return result_serializer.data





        share|improve this answer













        Based on @Hai Lang 's idea, I made a new namedtuple to add more info. Something like this:



        Serializer:
        No use ModelSerializer, use normal Serializer with field I would like to show on this view



        class UserSummarySerializer(serializers.Serializer):
        user_id = serializers.SerializerMethodField()
        last_name = serializers.SerializerMethodField()
        first_name = serializers.SerializerMethodField()
        display_summary = serializers.SerializerMethodField()

        def validate(self, data):
        #some validation if needed
        return data
        def get_user_id(self, obj):
        return obj.user.user_id
        def get_last_name(self, obj):
        return obj.user.last_name
        def get_first_name(self, obj):
        return obj.user.first_name
        def get_display_summary(self, obj):
        login_user = obj.login_user
        if obj.role_id==2 and login_user.role_id==1:
        return 1

        return 0


        then in my views:



        userSummary = namedtuple('userSummary ', ('user', 'login_user'))
        users = User.objects.filter(last_name__icontains='v')
        objs = [userSummary(u, login_user) for u in users]
        result_serializer = UserSerializer(objs, many=True)
        return result_serializer.data






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 5 '18 at 2:01









        LucVHLucVH

        112114




        112114






























            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%2f53370350%2fdjango-rest-framework-add-more-data-when-serialize-many-object%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







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)