How to convert django variable into json in template properly - django

I am using django-jsonify to convert django variable into json in javascript, and it returns such list
[{"pk": 4, "model": "api.post", "fields": {"summary": "Testing", "title": "My Test"}}, {"pk": 5, "model": "api.post", "fields": {"summary": "testing again", "title": "Another test"}}]
But desired list is
[{"pk": 4,"summary": "Testing", "title": "My Test"}, {"pk": 5,"summary": "testing again", "title": "Another test"}]

django-jsonify is just a thin wrapper around Django's builtin JSON model serializer. See:
https://bitbucket.org/marltu/django-jsonify/src/586ff1bbdd9b1c20e450015a093c146e58d40ddb/jsonify/templatetags/jsonify.py?at=default
If you want a different format, you'll have to define your own serializer. To do so, subclass the stdlib's json.JSONEncoder, and override the .default() method:
http://docs.python.org/2/library/json.html#json.JSONEncoder.default
You'll also need to hook up your own template tag (or pass the JSON via the view, etc) - but, as you can see in the django-jsonify source, that part isn't very much code.

Related

Can I create a Django Rest Framework API with Geojson format without having a model

I have a Django app that requests data from an external API and my goal is to convert that data which is returned as list/dictionary format into a new REST API with a Geojson format.
I came across django-rest-framework-gis but I don't know if I could use it without having a Model. But if so, how?
I think the best way is to use the python library geojson
pip install geojson
If you do not have a Model like in geodjango you have to explicitly describe the geometry from the data you have.
from geojson import Point, Feature, FeatureCollection
data = [
{
"id": 1,
"address": "742 Evergreen Terrace",
"city": "Springfield",
"lon": -123.02,
"lat": 44.04
},
{
"id": 2,
"address": "111 Spring Terrace",
"city": "New Mexico",
"lon": -124.02,
"lat": 45.04
}
]
def to_geojson(entries):
features = []
for entry in entries:
point = Point((entry["lon"], entry["lat"]))
del entry["lon"]
del entry["lat"]
feature = Feature(geometry=point, properties=entry)
features.append(feature)
return FeatureCollection(features)
if __name__ == '__main__':
my_geojson = to_geojson(data)
print(my_geojson)
Create the point geometry from lon, lat (Could also be another geometry type)
Create a feature with the created geometry and add the dictionary as properties. Note that I deleted lon, lat entries from the dictionary to not show up as properties.
Create A feature collection from multiple features
Result:
{"features": [{"geometry": {"coordinates": [-123.02, 44.04], "type":
"Point"}, "properties": {"address": "742 Evergreen Terrace", "city":
"Springfield", "id": 1}, "type": "Feature"}, {"geometry":
{"coordinates": [-124.02, 45.04], "type": "Point"}, "properties":
{"address": "111 Spring Terrace", "city": "New Mexico", "id": 2},
"type": "Feature"}], "type": "FeatureCollection"}
More Info here: Documentation Geojson Library

How can I filter django queryset again to get unique parameters?

Hi I am trying to receive one last message per user. I have filtered out messages but I am getting many messages for one user. How can I get last message of user.
queryset=MessageModel.objects.filter(
Q(sUser=self.request.user) | Q(rUser=self.request.user)
).order_by('-id')
return queryset
I am getting this list from filtering.
[
{
"message": "Hi b do you want to buy? 2",
"sUser": 1,
"rUser": 15,
"sent": true,
"pk": 8,
"user": {
"pk": 15
}
},
{
"message": "a to c",
"sUser": 1,
"rUser": 16,
"sent": true,
"pk": 7,
"user": {
"pk": 16
}
},
{
"message": "No thanks not buying this time",
"sUser": 15,
"rUser": 1,
"sent": false,
"pk": 6,
"user": {
"pk": 15
}
},
{
"message": "c to a",
"sUser": 16,
"rUser": 1,
"sent": false,
"pk": 4,
"user": {
"pk": 16
}
},
{
"message": "Hi b do you want to buy?",
"sUser": 1,
"rUser": 15,
"sent": true,
"pk": 1,
"user": {
"pk": 15
}
}
]
I want to get message with pk 8 and 7 only because it is the last message to user 15 and 16 but I am getting all messages for 15 and 16.
Ok I guess you are going for type like facebook messenger's dashboard. First get the related message of the user
relatedMessage=MessageModel.objects.filter(
Q(sUser=self.request.user) | Q(rUser=self.request.user)
).order_by('-id')
Add the first message to a list
convoList.append(relatedMessage.latest('id')) #since first message is unique
Then find out the friend from each one so that you can distinct who exactly the friend is (either sender or receiver which may be you or friend, since we are filtering message sender or receiver being you or your friend).
friend = message.sUser
if message.sUser==self.request.user:
friend=message.rUser
Great! You found which one your friend is.
Now for each message in relatedMessage check if message of you friend exist in your convoList or not. If it does not exist then add it to the convolist. Finally create serializer and return its data or queryset whichever you prefer.
This is preferred because it just makes one query to the database hence creating calculating part in the server. If you had first got related user from database then gone for again filtering message, it would be much costly due to huge query twice in database.
you have to
queryset=MessageModel.objects.filter(
Q(sUser=self.request.user) | Q(rUser=self.request.user)
).order_by('-id')
if queryset.exists():
return queryset[0]
else:
return None
Hope this will work for you
I'm not sure the Q expressions in your original query match what you asked for, but let's assume you want the most recent received message for every user and that you can depend on the ordering of id such that the higher the id the more recent.
If you are using a database backend that supports DISTINCT ON you can do the following:
most_recent_messages = MessageModel.objects.all().order_by('rUser', '-id').distinct('rUser')
You can add a filter instead of all if you want to filter the queryset further to particular users for example.

Cloudsearch dynamic fields skipping fields

In cloudsearch (using IMDB data) I added two dynamic fields to the existing indexing options
I then got the entire JSON IMDB data from AWS and added the fields location_t and month_i.
[{
"fields": {
"rating": 7.4,
"genres": ["Comedy", "Drama"],
"plot": "A New Jersey guy dedicated to his family, friends, and church, develops unrealistic expectations from watching porn and works to find happiness and intimacy with his potential true love.",
"release_date": "2013-01-18T00:00:00Z",
"title": "Don Jon",
"rank": 1,
"running_time_secs": 5400,
"directors": ["Joseph Gordon-Levitt"],
"image_url": "http://ia.media-imdb.com/images/M/MV5BMTQxNTc3NDM2MF5BMl5BanBnXkFtZTcwNzQ5NTQ3OQ##._V1_SX400_.jpg",
"year": 2013,
"actors": ["Joseph Gordon-Levitt", "Scarlett Johansson", "Julianne Moore"]
},
"type": "add",
"id": "tt2229499",
"location_t": "Berlin",
"month_i": 8},...
When I uploaded the JSON, it ignored the dynamic fields?
I did it anyway and I tried searching but to no avail. Anyone no what I am doing wrong. I followed the instructions to the book in dynamic fields
You need to have your dynamic fields as a part of your fields array, see below:
[{
"fields": {
"rating": 7.4,
"genres": ["Comedy", "Drama"],
"plot": "A New Jersey guy dedicated to his family, friends, and church, develops unrealistic expectations from watching porn and works to find happiness and intimacy with his potential true love.",
"release_date": "2013-01-18T00:00:00Z",
"title": "Don Jon",
"rank": 1,
"running_time_secs": 5400,
"directors": ["Joseph Gordon-Levitt"],
"image_url": "http://ia.media-imdb.com/images/M/MV5BMTQxNTc3NDM2MF5BMl5BanBnXkFtZTcwNzQ5NTQ3OQ##._V1_SX400_.jpg",
"year": 2013,
"actors": ["Joseph Gordon-Levitt", "Scarlett Johansson", "Julianne Moore"],
"location_t": "Berlin",
"month_i": 8
},
"type": "add",
"id": "tt2229499",},...

Django - serialize to JSON, how to serialize a FK User object

I'm on a page which sends a request to server side for a list of comments of current topic.
like this
localhost:8000/getComments/567 , while 567 is the topic id.
then, in my django view, like this:
def getProjectComments(request, pId):
format = 'json'
mimetype = 'application/javascript' #'application/xml' for 'xml' format
comments = PrjComment.objects.filter(prj=pId)
data = serializers.serialize(format, comments)
return HttpResponse(data,mimetype)
Now , the question is ,
when I try to use jQuery.parseJSON(data) at the browser side.
[
{
"pk": 10,
"model": "app.prjcomment",
"fields":
{
"status": 1,
"time_Commented": "2011-12-11 17:23:56",
"prj": 1,
"content": "my comment 1",
"user": 25
}
},
{
"pk": 9,
"model": "app.prjcomment",
"fields": {
"status": 1,
"time_Commented": "2011-12-11 17:23:51",
"prj": 1,
"content": "comment \u4e00\u4e2a",
"user": 33
}
} ..
I need to use some detail information of user object. (user is a Foreign Key in model PrjComment)
such as user.first_name to display on the comment list.
but here it is only an id for user.("user": 33)
How can I do that? Anyone who can kind help?
Thank you very much
the User is the Django auth_user.
The easy solution would be to specify the values you need:
comments = PrjComment.objects.filter(prj=pId) \
.values('status','time_commented','prj','content','user__id',
'user__username','user__first_name')
Update:
To access your userprofile information use the table name as defined in your AUTH_PROFILE_MODULE setting. In my case the table is called userprofile, and I'd access the data like this:
values('user__userprofile__moreinfo')
where moreinfo is the field you're interested in

Do fixtures with relationships work in app-engine-patch?

I have a fixture with multiple models that I'm using for testing. It
works for the basic models, but fails to create the entities for the
models with relationships. Is this a known limitation of app-engine-patch or am I missing
something? I'm using JSON for the fixture file.
I'm creating the fixture file with 'manage.py dumpdata --format=json >> file.json'
Here are the models involved:
class BibleBook(db.Model):
name = db.StringProperty(required=True)
description = db.TextProperty(required=True)
class Task(db.Model):
name = db.StringProperty(required=True)
description = db.TextProperty(required=True)
energy = db.IntegerProperty(default=1)
focus = db.IntegerProperty(default=0)
empathy = db.IntegerProperty(default=0)
denarii = db.IntegerProperty(default=0)
talents = db.IntegerProperty(default=0)
experience = db.IntegerProperty(default=1)
percent_per_task = db.IntegerProperty(default=5)
bibleBook = db.ReferenceProperty(BibleBook)
level = db.StringProperty(required=True, choices=set(["Catachumen", "Laymen", "Elder"]))
drop_percentage = db.IntegerProperty(default=10)
The json in the fixture file looks like this:
[
{"pk": "ag5sYXctYW5kLWdvc3BlbHIcCxIWbGF3YW5kZ29zcGVsX2JpYmxlYm9vaxgDDA",
"model": "lawandgospel.biblebook",
"fields": {"name": "Luke", "description": "Description"}},
{"pk": "ag5sYXctYW5kLWdvc3BlbHIXCxIRbGF3YW5kZ29zcGVsX3Rhc2sYBQw",
"model": "lawandgospel.task",
"fields": {"empathy": 0, "name": "Study Luke", "level": "Catachumen", "energy": 1,
"focus": 0, "experience": 1, "drop_percentage": 10, "talents": 0,
"bibleBook": "ag5sYXctYW5kLWdvc3BlbHIcCxIWbGF3YW5kZ29zcGVsX2JpYmxlYm9vaxgDDA",
"percent_per_task": 5, "denarii": 0, "description": "The Book of Luke"}}
]
The BibleBook model loads properly, but the Task one does not.
I'm checking this by doing:
books = BibleBook.gql('')
self.assertEquals(books.count(), 1)
tasks = Task.gql('')
self.assertEquals(tasks.count(), 1)
The first test passes, but the second does not.
Thanks,
Brian Yamabe
Thanks, celopes, for asking for the additional code. I decided to play with the json file and fixed the problem by using simple numbers for the pk's. Here's the JSON that fixes the problem for the models and tests I posted:
[
{"pk": "1",
"model": "lawandgospel.biblebook",
"fields": {"name": "Luke", "description": "The Gospel According to St. Luke."}},
{"pk": "2",
"model": "lawandgospel.task",
"fields": {"empathy": 0, "name": "Study the Gospel of Luke", "level": "Catachumen",
"energy": 1, "focus": 0, "experience": 1, "drop_percentage": 10, "talents": 0,
"bibleBook": "1", "percent_per_task": 5, "denarii": 0,
"description": "The Book of Luke"}}
]