I am wondering how to pass some context data to response in Django.
I have this endpoint:
/api/facebook/user/
which returns data like this:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"facebook_account_id": "176890406129409",
"first_name": "Ivan",
"last_name": "K",
"token_status": "active",
"facebook_access_token": 1
},
{
"facebook_account_id": "123123123",
"first_name": "Ivan",
"last_name": "FFFF",
"token_status": null,
"facebook_access_token": null
},
{
"facebook_account_id": "123123",
"first_name": "Test",
"last_name": "test",
"token_status": null,
"facebook_access_token": null
}
]
Here is my list serializer:
class FacebookUserListSerializer(ModelSerializer):
token_status = SerializerMethodField()
class Meta:
model = FacebookUser
fields = ["facebook_account_id", "first_name", "last_name", "token_status", "facebook_access_token"]
def get_token_status(self, obj):
try:
facebook_token = obj.facebook_access_token
if facebook_token:
return "active" if facebook_token.is_active else "inactive"
except FacebookToken.DoesNotExist:
return None
Here is my list view:
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
data = response.data
inactive_accounts = sum(1 for account in data if account.get("token_status") == "inactive")
accounts_without_token = sum(1 for account in data if account.get("token_status") is None)
context = {"inactive_accounts": inactive_accounts, "accounts_without_token": accounts_without_token} # Is this the correct way of passing context data to a response?
response.context_data = context
return response
In list view, in the "context" variable, I am attempting to pass data to the frontend, but I am sure that I am doing this incorrectly, I must first convert it to JSON, or make this somewhere else.
So the question is – where (serializer, list method, or somewhere else?) and how should I put this context data according to REST conventions, so that data can be accessed in frontend without iterating over list items?
2
Answers
you can do something like this:
but in the front end you will have to fetch this values using chained key like
data.context.inactive_accounts
or you can simply add key directly to response without defining separate context.
then at frontend you can directly fetch with related keys
data.inactive_accounts
Do not loop through serialized data to find the information you want, use the view
queryset
instead. Also, there is no need to convert your response, DRFResponse
handles it automatically, given the correctcontent-type
.Since the extra information is not directly related to your object, doing it inside the
list
method is just fine. Else, you would useget_serializer_context
method.Here is a more "advanced" way on how to extract this information, using
aggregation
:views.py