Django Rest Framework - Nested relationships as Flat - django

http://www.django-rest-framework.org/api-guide/relations/#nested-relationships
It is not clear from the documentation if and how it's possible to use the same principle of nested relationships to render a flat JSON.
For example:
"nest": {
"b": {
"c": {
"d": {
"e": {
"E": "echo"
},
"D": "delta"
},
"C": "charlie"
},
"B": "beta"
},
"A": "alpha"
}
"flat": {
"A": "alpha",
"B": "beta",
"C": "charlie",
"D": "delta",
"E": "echo"
}
How can the flat JSON be achieved?

Lets assume your code looks like
mymodel_queryset = MyModel.objects.all()
So what you can do is write your own custom serializer as follows:
def my_custom_serializer(queryset):
res = []
for q in queryset:
ob = {'name': q.name, 'city': q.city.name} # Notice how i use the relation here for city. So the nested relation is becoming flat for city
res.append(ob)
return res
Now in your code you can use
data = my_custom_serializer(mymodel_queryset)
return Response(status=status.HTTP_200_OK, data=data)
Hope this helps you. :)

Related

Change hierarchy of a dictionary of lists

I have a dictionary that contains a list of dictionaries, of which one of the elements (C) contains another list of dictionaries. The structure is as follows:
{
"fruits":
[
{
"A": "apple",
"B": "banana",
"C":
[
{
"D": "Green grape",
"E": "Red grape",
}
{
"D": "Orange",
"E": "Grapefruit",
}
]
}
],
"vegetables":
etc...
}
I would like to move the elements D & E up a hierarchy while removing C. The resulting dictionary should look as follows.
{
"fruits":
[
{
"A": "apple",
"B": "banana",
"D": "Green grape",
"E": "Red grape",
},
{
"A": "apple",
"B": "banana",
"D": "Orange",
"E": "Grapefruit",
}
]
"vegetables":
etc...
}
Any suggestions?

How can i group by all data according to model in DRF?

Currently, I am working on a DFR project where can successfully get all data but i need some modify with the json data.
Here Is the code
class PermissionSerializers(serializers.ModelSerializer):
class Meta:
model = Permission
fields = ['id', 'name', 'codename']
def to_representation(self, instance):
return {
'model': instance.content_type.name,
'data' :{
'id': instance.id,
'name': instance.name,
'codename': instance.codename,
}
}
And i get this JSON format,
{
"next": "http://127.0.0.1:8000/en/ga/api-version/common/admin/permissions/?page=4",
"previous": "http://127.0.0.1:8000/en/ga/api-version/common/admin/permissions/?page=2",
"total": 33,
"page": 3,
"page_size": 10,
"results": [
{
"model": "user",
"data": {
"id": 25,
"name": "Can add user",
"codename": "add_user"
}
},
{
"model": "user",
"data": {
"id": 29,
"name": "Admistrative Access",
"codename": "admin_access"
}
},
But I want to modify with something like this which has model name on top and then all available data inside a dictionary:
{
"model": "user",
"data": {
"id": 26,
"name": "Can change user",
"codename": "change_user"
},
{
"id": 25,
"name": "Can add user",
"codename": "add_user"
},
},
You get something like this because you have pagination in your API, if you don't want it just disable pagination.
I came up with this solution:
def list(self, request):
_models_list = [
'organization','user','group', 'logentry', 'organizationtype',
'keyword', 'productsupport','feedbacksupport','twittercredential']
models = ContentType.objects.filter(model__in = _models_list)
model_dict = {
'model': '',
'data':''
}
results = []
for model in models:
_permissions = []
access = ' Access'
if model.model == 'group':
model_dict['model'] = 'Role'+ access
elif model.model == 'organizationtype':
model_dict['model'] = 'Organization Type'+ access
elif model.model == 'productsupport':
model_dict['model'] = 'Product'+ access
elif model.model == 'feedbacksupport':
model_dict['model'] = 'Feedback'+ access
else:
model_dict['model'] = model.model.capitalize()+ access
permissions = Permission.objects.filter(content_type = model)
for premission in permissions:
_permissions.append(premission)
serializer = PermissionSerializers(_permissions, many=True)
data = serializer.data
model_dict['data'] = data
results.append(model_dict.copy())
return Response(results)

mongodb find a pattern of an input

I need to find all the results that start with certain input for example for the inputs: "Paul", "pau", "paul Gr", "Paul Green", "Paul Gree" , "Pel", "pele", "joh","john" etc.. The search has to be case insensive..
it suppose to return all of these(the input search string is at least 3 characters long):
[
{
"_id": ObjectId("5e6ffe413f71835ae3aa4b60"),
"f": "Paul",
"id": 11811,
"l": "Pelè",
"r": 64
},
{
"_id": ObjectId("5e6ffe413f71835ae3aa4b65"),
"f": "paul",
"id": 11811,
"l": "walker",
"r": 64
},
{
"_id": ObjectId("5e6ffe413f71835ae3aa4b66"),
"f": "johnny",
"id": 11811,
"l": "Green",
"r": 64
}
]
tried to do the following:
contain_searched_term_players = list(db.players_collection.find({'$or': [{'f': {'$regex': searched_player_name_string, '$options': 'i'}},
{'l': {'$regex': searched_player_name_string, '$options': 'i'}},
{'c': {'$regex': searched_player_name_string, '$options': 'i'}}]}).sort([{'r', -1}])
but it doesnt work for "Paul Green"
searched_player_name_string is the given input(the inputs above, for example Paul Green)
You need to provide correct Regex for query condition
^(Paul Green|Paul Gree|Paul|paul|pau|Gr|pele|Pel|john|joh)
RegexPlayground
searched_player_name_string = "^(Paul Green|Paul Gree|Paul|paul|pau|Gr|pele|Pel|john|joh)"
result_cursor = db.players_collection.find({
"$or": [
{
"f": {
"$regex": searched_player_name_string,
"$options": "i"
}
},
{
"l": {
"$regex": searched_player_name_string,
"$options": "i"
}
},
{
"c": {
"$regex": searched_player_name_string,
"$options": "i"
}
}
]
})
searched_player_name_string = list(result_cursor)
MongoPlayground
Split your input in separate strings, run the query on each and append the results together (checking first it's not already found), Finally sort the results:
searched_player_name_string = 'Paul Green'
found_players = []
for regex in searched_player_name_string.split():
contain_searched_term_players = db.players_collection.find({'$or': [{'f': {'$regex': regex, '$options': 'i'}},
{'l': {'$regex': regex, '$options': 'i'}},
{'c': {'$regex': regex, '$options': 'i'}}]})
for player in contain_searched_term_players:
# The next line avoids creating duplicate answers if there are multiple matches for the same player
if player['_id'] not in [ o['_id'] for o in found_players ]:
found_players.append(player)
# Sort the output by "r" - highest first
pprint.pprint(sorted(found_players, key=lambda o: o['r'], reverse=True))

How to nest a serializer?

So I'm trying to create an /api/info url that return various data on my application. It pulls data from various models and puts it together in one response. I got the following:
class SessionInfo(generics.GenericAPIView):
def get(self, request, format=None):
token = Token.objects.get(user=self.request.user)
userprofile = UserProfile.objects.get(user=self.request.user)
is_admin = self.request.user.is_staff
is_primary_owner = userprofile.primary_owner
managers = userprofile.reports_to.all()
man = ["test manager 1", "test manager 2"]
pages = Page.objects.filter(published=True, show_in_menu=True)
pages_output = JSONRenderer().render(PageSerializer(pages).data)
content = {
'user': {
"username": str(self.request.user.username),
"first_name": str(self.request.user.first_name),
"last_name": str(self.request.user.last_name),
"is_admin": is_admin,
"is_primary_owner": is_primary_owner,
"api_token": token.key,
"timezone": 'blalala',
"managers": man,
},
'license': {
"plan" : "gold",
"expiry_date" : "lol",
},
'feature_flags': {
'billing_test': False,
},
'pages': { pages_output },
}
return Response(content)
However it doesn't properly serialize and render pages, making it an escaped string instead:
{
"feature_flags": {
"billing_test": false
},
"user": {
"username": "test#user.com",
"first_name": "Test",
"last_name": "User",
"is_admin": true,
"managers": [
"test manager 1",
"test manager 2"
],
"api_token": "08d1a5827da9a90e7746949ffd2e69e87c51b272",
"timezone": "blalala",
"is_primary_owner": false
},
"license": {
"expiry_date": "lol",
"plan": "gold"
},
"pages": [
"[{\"id\": 1, \"title\": \"Trololol\"}, {\"id\": 2, \"title\": \"NEW pages\"}]"
]
}
if I use directuly use pages_output = PageSerializer(pages) I get:
<webapp_api_v1.serializers.PageSerializer object at 0x10a0d8f90> is not JSON serializable
How can I make a serializer properly nest within my constructed response? Thanks!
Solved it with pages_output = PageSerializer(pages).data and changing 'pages': pages_output,

Parsing a Django-mptt JSON

I have created created a dictionary from Django-mptt and used json.dump() to get the JSON object.
{
"a": "cat1",
"c": ["item2", "item1"],
"b": [
{"a": "burgers", "c": [], "b": []},
{"a": "south indian", "c": [], "b": []},
{"a": "veg subs", "c": ["corn and peas", "a;loo patty", "paneer delite"], "b": []},
{"a": "traditional", "c": ["subway melt", "Chicken ranch", "turkey", "Subway club"], "b": []},
{"a": "favourites", "c": ["tuna", "chicken ham", "roasted chicken"], "b": []},
{"a": "beverages", "c": [], "b": []},
{"a": "north indian", "c": [], "b": []},
{"a": "oriental", "c": [], "b": []},
{"a": "european ", "c": [], "b": []}
]
}
Here, "cat1" is the main category, having sub-categories children, burgers, traditional, favourites etc. Any category can have sub-categories.
a - Category name
c - Items list
b - Children
This is my JSON object. What do I use to show this JSON object in tree format in JavaScript.
I need to display the First children of the every category clicked. And for every Category clicked, I want to display the items below the tree structure.