Does mongoengine have a similar method to populate
db.collection.posts.findById(id).populate('user_id')
day goes by but still I didn't saw anything that there is an API documentation related to .populate() in mongoengine and I chose to make my own way.
mongoengine is an Object-Oriented driver, compare to mongoose there is already predefined function .populate() but if you know how OOP works it is just a piece of cake for you, here is a simple trick
# .schema.author.py
class Author(Document):
name = StringField(required=True)
# .schema.book.py
class Book(Document):
title = StringField()
author = ReferenceField(Author)
def tojson(self):
json = {
'title ': self.title ,
'author ': self.author,
}
json['author'] = self.author.name
return json
# .route.book.py
def get(self):
try:
books = []
for book in Book.objects:
books.push(book.tojson())
return {'status': True, 'response': books}
except Exception as e:
print(e)
and the expected result must be populated Author for each Book object
{
"status": true,
"response": [
{
"title": "<book-name>",
"author": {
"name": "<author-name>"
}
}
]
}
I am not an expert in MongoEngine, but you can query like this:
post = Posts.objects(id=id).first()
That returns the data from that Model and it's already populated. You can access the author of the post using:
post.author.name
Related
I am new on graphql and working with some datasets that is returned as a list of dictionaries.
snippet code:
class Player(ObjectType):
username = String()
role = String()
class Game(ObjectType):
players = List(Player)
I'm wondering why below code doesn't work?
class Query(ObjectType):
game_info = Field(Game, username=String(), role=String())
def resolve_game_info(self, info):
results = [{
"username":"Malphite",
"role":"tank"
},
{
"username":"Teemo",
"role":"support"
}]
output = []
for res in results:
output.append(
Player(
username=res['username'],
role=res['role']
)
)
return output
How I query in graphql:
query {
game_info(username:"Teemo") {
players {
username
role
}
}
}
Results to like this:
{
"data": {
"gameInfo": null
}
}
Any help would this would be greatly appreciated!
The problem seems in format of returned data. Suppose, you have more fields in your Game, not only players. There is no way of including those fields in your return format.
Instead of return output .
Try: return {'players':output}
I would like to map object from another API and send in GET response. I'm going to change only id of received object. Let's assume I get data from another API in such format:
{
"id": "31242",
"name": "sth1",
"price": "44",
"data": "2017-06-07",
}
In my database I have table object1 with values:
{
"id": "123",
"name": "sth1",
},
{
"id": "124",
"name": "sth2",
},
{
"id": "125",
"name": "sth3",
}
Field name is unique both in data from API and in data from database. I receive an object named sth1. So now I would like to find it in my database and get his id, replace with id from API and send GET response. In this case my response would look in this way:
{
"id": "123",
"name": "sth1",
"price": "44",
"data": "2017-06-07",
}
At this moment this is my URL - url(r'^data/(?P<name>\w+)$', views.DataList),
but I would like to have such URL - localhost:8000/data?name=sth
Myview.py:
#api_view(['GET'])
def DataList(request, name=None):
if request.method == 'GET':
quote = getDataFromAPI().get(name)
return Response(quote)
serializers.py:
class Object1Serializer(serializers.ModelSerializer):
class Meta:
model = Object1
depth = 1
fields = '__all__'
models.py:
class Object1(models.Model):
name = models.CharField(max_length=200)
I have done it in this way:
#api_view(['GET'])
def DataList(request):
t = request.GET.get("t","")
quote = getDataFromAPI().get(t)
id = Object1.objects.get(t=t)
quote["id"] = id
return Response(quote)
But I get error:
TypeError: Object of type 'Object1' is not JSON serializable
I suppose, your view should look somewhat like this,
#api_view(['GET'])
def DataList(request):
t = request.GET.get("t","")
quote = getDataFromAPI().get(t)
id = Object1.objects.get(t=t).id #put the id of the object in the variable.
#not the object itself.
quote["id"] = id
return Response(quote)
If you want to change the url from
url(r'^data/(?P<name>\w+)$', views.DataList) to localhost:8000/data?name=sth you'd need to change your api endpoint from
#api_view(['GET'])
def DataList(request, name=None):
to
#api_view(['GET'])
def DataList(request):
name = request.GET.get("name","")
and then take the id of object from your database by querying
id = Object1.objects.get(name=name)
and then updating id in response to be sent
quote["id"] = id
I'm newbie in Python and building API in Django using rest framework and using mysql for database.
I'm using filter query to get user info object but its returning array.
In Login API my code is:
is_valid_user = users.objects.filter(email=req_email, password=req_password)
serializer = usersSerializer(is_valid_user,many=True)
if is_valid_user:
response = {
'message': 'success',
'code': 1,
'data':serializer.data
else:
response = {
'message': 'User not found',
'code': 0,
}
return Response(response)
My usersSerializer Class :
class usersSerializer(serializers.ModelSerializer):
class Meta:
model = users
fields = ('uid', 'first_name', 'last_name', 'email', 'gender')
For this code response is :
{
"message": "success",
"code": 1,
"data": [
{
"uid": 6,
"first_name": "anuj",
"last_name": "sharma",
"email": "anujs1991#gmail.com",
"gender": "0"
}
]
}
But for this I don't want array of data .
Expected result should be :
{
"message": "success",
"code": 1,
"data": {
"uid": 6,
"first_name": "anuj",
"last_name": "sharma",
"email": "anujs1991#gmail.com",
"gender": "0"
}
}
Kindly help me for this.
The comments under your questions should point you to another solution. Here I'd like to give an explanation, why you're getting an array, and not an object.
In this line:
isValidUser = users.objects.filter(email=req_email, password=req_password)
you use the filter method, which may return more than 1 result (or none). You'll always get an array (a list in python), regardless of the number of results. The filter() method returns a new QuerySet.
If you want to retrieve a single result explicitly, and you have a unique field in your model class, then you should use the method get(), which doesn't return a QuerySet, but an object.
So if, let's say the field email is set to be unique, you could do this:
isValidUser = users.objects.get(email=req_email)
That will return an object, if there is an entry that can be matched.
Also, it is a good practice to follow the naming conventions for Python and name the variables with snake case:
is_valid_user
instead of
isValidUser
I have the following two classes in my app.models and i'm using the wagtail APIs to get the data as json
class AuthorMeta(Page):
author=models.OneToOneField(User)
city = models.ForeignKey('Cities', related_name='related_author')
class Cities(Page):
name = models.CharField(max_length=30)
So, when I try /api/v1/pages/?type=dashboard.AuthorMeta&fields=title,city, it returns the following data:
{
"meta": {
"total_count": 1
},
"pages": [
{
"id": 11,
"meta": {
"type": "dashboard.AuthorMeta",
"detail_url": "http://localhost:8000/api/v1/pages/11/"
},
"title": "Suneet Choudhary",
"city": {
"id": 10,
"meta": {
"type": "dashboard.Cities",
"detail_url": "http://localhost:8000/api/v1/pages/10/"
}
}
}
]
}
In the city field, it returns the id and meta of the city. How can I get the name of the city in the response here, without making an extra query? :/
I couldn't find any solution in the Documentation. Am I missing something?
Use Django model property to return through the ForeignKey:
class AuthorMeta(Page):
author=models.OneToOneField(User)
city = models.ForeignKey('Cities', related_name='related_author')
city_name = property(get_city_name)
def get_city_name(self):
return self.city.name
Check Term Property to better understand the concept
In case you have the foreign key in a Streamfield, e.g. a PageChooserBlock, you can customize the api response by overwriting the get_api_representation of a block, as described in the example as provided here:
class CustomPageChooserBlock(blocks.PageChooserBlock):
""" Customize the api response. """
def get_api_representation(self, value, context=None):
""" Return the url path instead of the id. """
return value.url_path
I want to grab some information from Foursquare , add some fields and return it via django-tastypie.
UPDATE:
def obj_get_list(self, request=None, **kwargs):
near = ''
if 'near' in request.GET and request.GET['near']:
near = request.GET['near']
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
client = foursquare.Foursquare(client_id=settings.FSQ_CLIENT_ID, client_secret=settings.FSQ_CLIENT_SECRET)
a = client.venues.search(params={'query': q, 'near' : near, 'categoryId' : '4d4b7105d754a06374d81259' })
objects = []
for venue in a['venues']:
bundle = self.build_bundle(obj=venue, request=request)
bundle = self.full_dehydrate(bundle)
objects.append(bundle)
return objects
Now I am getting:
{
"meta": {
"limit": 20,
"next": "/api/v1/venue/?q=Borek&near=Kadikoy",
"offset": 0,
"previous": null,
"total_count": 30
},
"objects": [
{
"resource_uri": ""
},
{
"resource_uri": ""
}]
}
There are 2 empty objects. What should I do in order to fill this resource?
ModelResource is only suitable when you have ORM Model behind the resource. In other cases you should use Resource.
This subject is discussed in ModelResource description, mentioning when it is suitable and when it is not: http://django-tastypie.readthedocs.org/en/latest/resources.html#why-resource-vs-modelresource
Also there is a whole chapter in the documentation, aimed at providing the details on how to implement non-ORM data sources (in this case: external API): http://django-tastypie.readthedocs.org/en/latest/non_orm_data_sources.html