1

I'm able to access the correct fields ('author.username') when I execute the query.

But if I run that same query through the serializer, it doesn't print out the select_related model fields.

Should I be specifying all fields, plus the additional fields of the foreignkey model??

views.py

query = Chat.objects.select_related('author').filter(id=chat.id)
print(query)    # [<Chat: 108>]
print(query[0]) # 108
print(query[0].author.username) # superman



context = serializers.serialize("json", Chat.objects.select_related('author').filter(id=chat.id))
print("---------")
print(context) # [{"model": "chats.chat", "pk": 108, "fields": {"author": 29, "text": "this is a message", "chatroom": 11, "written_at": "2016-01-07T23:03:28.968Z"}}]

--- Updated --- views.py

context = ChatSerializer(chat)

# output
{u'text': u'come on', u'chatroom': OrderedDict([(u'id', 11), ('created_at', u'2016-01-07T00:27:28.391467Z'), ('creator', 29), ('participant', 1)]), u'written_at': u'2016-01-08T01:12:20.310776Z', u'author': OrderedDict([(u'id', 29), ('password', u'pbkdf2_sha256$24000$h0whlzx0BleT$4cUWdRkUsPYB7Ia6F+pYxX+31BMhJJfpWiLHfoL9NOY='), ('last_login', u'2016-01-07T00:26:37.907507Z'), ('email', u'superman@gmail.com'), ('username', u'superman'), ('first_name', u'clark'), ('last_name', u'kent'), ('is_active', True), ('is_admin', False), ('joined_on', u'2016-01-06T23:57:43.191484Z'), ('is_online', False), ('is_contractor', False), ('profile_pic', '/media/bicycle_z3NDBPI.jpeg'), ('braintree_id', u'20401140'), ('braintree_client_token', u'eyJ2ZXJzaW9uIjoyLCJhdXRob3JpemF0aW9uRmluZ2VycHJpbnQiOiI1MjIxM2UwZDQ4OGM0MmFkNTYzY2IzMDJlMDBkMmIyMWIwZWEzYzBiNWEzZTg2ZmNhMmJlNWM3MTI5YjNmNGJifGNyZWF0ZWRfYXQ9MjAxNi0wMS0wNlQyMzo1Nzo0NC42MTgzNzQ2NTgrMDAwMFx1MDAyNmN1c3RvbWVyX2lkPTIwNDAxMTQwXHUwMDI2bWVyY2hhbnRfaWQ9ZGZ6amRrdHM1ZnNxeXF0alx1MDAyNnB1YmxpY19rZXk9ZGtta245cDNjNTQzZGhudyIsImNvbmZpZ1VybCI6Imh0dHBzOi8vYXBpLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb206NDQzL21lcmNoYW50cy9kZnpqZGt0czVmc3F5cXRqL2NsaWVudF9hcGkvdjEvY29uZmlndXJhdGlvbiIsImNoYWxsZW5nZXMiOltdLCJlbnZpcm9ubWVudCI6InNhbmRib3giLCJjbGllbnRBcGlVcmwiOiJodHRwczovL2FwaS5zYW5kYm94LmJyYWludHJlZWdhdGV3YXkuY29tOjQ0My9tZXJjaGFudHMvZGZ6amRrdHM1ZnNxeXF0ai9jbGllbnRfYXBpIiwiYXNzZXRzVXJsIjoiaHR0cHM6Ly9hc3NldHMuYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJhdXRoVXJsIjoiaHR0cHM6Ly9hdXRoLnZlbm1vLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJhbmFseXRpY3MiOnsidXJsIjoiaHR0cHM6Ly9jbGllbnQtYW5hbHl0aWNzLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb20ifSwidGhyZWVEU2VjdXJlRW5hYmxlZCI6ZmFsc2UsInBheXBhbEVuYWJsZWQiOnRydWUsInBheXBhbCI6eyJkaXNwbGF5TmFtZSI6ImthbGxhcm9vIiwiY2xpZW50SWQiOm51bGwsInByaXZhY3lVcmwiOiJodHRwOi8vZXhhbXBsZS5jb20vcHAiLCJ1c2VyQWdyZWVtZW50VXJsIjoiaHR0cDovL2V4YW1wbGUuY29tL3RvcyIsImJhc2VVcmwiOiJodHRwczovL2Fzc2V0cy5icmFpbnRyZWVnYXRld2F5LmNvbSIsImFzc2V0c1VybCI6Imh0dHBzOi8vY2hlY2tvdXQucGF5cGFsLmNvbSIsImRpcmVjdEJhc2VVcmwiOm51bGwsImFsbG93SHR0cCI6dHJ1ZSwiZW52aXJvbm1lbnROb05ldHdvcmsiOnRydWUsImVudmlyb25tZW50Ijoib2ZmbGluZSIsInVudmV0dGVkTWVyY2hhbnQiOmZhbHNlLCJicmFpbnRyZWVDbGllbnRJZCI6Im1hc3RlcmNsaWVudDMiLCJiaWxsaW5nQWdyZWVtZW50c0VuYWJsZWQiOnRydWUsIm1lcmNoYW50QWNjb3VudElkIjoia2FsbGFyb28iLCJjdXJyZW5jeUlzb0NvZGUiOiJVU0QifSwiY29pbmJhc2VFbmFibGVkIjpmYWxzZSwibWVyY2hhbnRJZCI6ImRmempka3RzNWZzcXlxdGoiLCJ2ZW5tbyI6Im9mZiJ9'), ('payment_method_nonce', u'dbd01080-35e2-4a3b-a695-560491a14567'), ('payment_method_token', u'cfty3w')])}

console.log() output

ChatSerializer(<Chat: 118>):
    author = NestedSerializer(read_only=True):
        id = IntegerField(label='ID', read_only=True)
        password = CharField(max_length=128)
        last_login = DateTimeField(allow_null=True, required=False)
        email = EmailField(max_length=255, validators=[<UniqueValidator(queryset=User.objects.all())>])
        username = CharField(max_length=80)
        first_name = CharField(max_length=45)
        last_name = CharField(max_length=45)
        is_active = BooleanField(required=False)
        is_admin = BooleanField(required=False)
        joined_on = DateTimeField(read_only=True)
        is_online = BooleanField(required=False)
        is_contractor = BooleanField(required=False)
        profile_pic = ImageField(allow_null=True, required=False)
        braintree_id = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
        braintree_client_token = CharField(allow_blank=True, allow_null=True, max_length=2000, required=False)
        payment_method_nonce = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
        payment_method_token = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
    text = CharField(max_length=255)
    chatroom = NestedSerializer(read_only=True):
        id = IntegerField(label='ID', read_only=True)
        created_at = DateTimeField(read_only=True)
        creator = PrimaryKeyRelatedField(queryset=User.objects.all())
        participant = PrimaryKeyRelatedField(queryset=Contractor.objects.all())
    written_at = DateTimeField(read_only=True)
Chris
  • 449
  • 1
  • 9
  • 18

2 Answers2

3

The Django's serializer doesn't support it: ticket. I suggest you using the Django Rest Framework.

Alex Morozov
  • 5,823
  • 24
  • 28
  • Thanks. I went through the documentation and created my serializer. When I print the data out after passing it through the serializer, it looks good. However, when I push it through the redis.publish(), it comes out only as the django model fields - not the actual key:values. Added the outputs up top. – Chris Jan 08 '16 at 01:25
  • I was actually able to grab it. I wasn't calling it properly. Should be context.data – Chris Jan 08 '16 at 01:47
1

Joining the Tables using the Foreign Key is what you are searching for I guess

READ IT CAREFULLY IT'S LONG BUT WORTH READING

Just assume that you have 2 models:- Employee and Organization

Organization(models.Model):
  organization_name = models.CharField()

Employee(models.Model):
  employee_name = models.CharField()
  employee_organization= models.ForeignKey(Organzation,on_delete=models.CASCADE)

And you have to access Employee Model in the frontend but the data you receive is:

data : { 
         employee_name:"some_employee_name",
         employee_organization:"some_org_id" #Here you are getting org_id but 
                                             #that's not what you want I assume
       }

But what you really want to get in the frontend is:-

data : {
        employee_name:"some_employee_name",
        employee_organization: {
                              organization_name:"some_organization_name"
                              }
       }

So that you can access the "Organization Name" instead of "Organization ID". This is called Joining the table using the Foreign Key.

For that you have to create the Serializers for the models like this:-

 OrganizationSerializer(serializer.ModelSerializer):
    model = models.Organization
    field = "__all__"

 EmployeeSerializer(models.Model):
    employee_organization = OrganizationSerializer() # This does the trick
    model = models.Employee
    fields = "__all__"

You should return the data to the frontend using the EmployeeSerializer normally in your View like this:-

class EmployeeView(APIView):
    def get(self, request, format=None):
        queryset= models.Employee.objects
                        .select_related("employee_organization")
                        .get(id="some_employee_id")

        serializer = serializers.EmployeeSerializer(queryset)

        return Response(serializer.data)

Now you will get the required data as:-

 data : {
            employee_name:"some_employee_name",
            employee_organization: {
                                  organization_name:"some_organization_name"
                                 }
        }

Now you can extract the "organization_name" however you want.