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

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

Related

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.

django-rest-framework-datatables and Django Parler's translation field

I've got model with translated fields.
class Device(TranslatableModel):
translations = TranslatedFields(name=models.CharField(max_length=100))
I made a serializer like:
class DeviceSerializer(TranslatableModelSerializer):
translations = TranslatedFieldsField(shared_model=Device)
class Meta:
model = Device
fields = ('translations',)
It gives me nice JSON like it should.
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"device": {
"translations": {
"en": {
"name": "Sample Device"
}
}
}
}
]
}
Now i want to use it with django-rest-framework. In my template I've written script like:
$('#devices').DataTable({
'serverSide': true,
'ajax': 'api/devices/?format=datatables',
'columns': [
{'data':'device.translations.en'}
It refuses to work with me. I am getting django.core.exceptions.FieldError: Unsupported lookup 'en' for AutoField or join on the field not permitted.
If I am not appending .en to {'data'} it gives Object.object of course.
Issue is in template file.
Pass name & data field separately to columns in data-table configuration
please replace field_name with your model field name
$('#devices').DataTable({
'ajax': 'api/devices/?format=datatables',
'columns': [
{"data": "translations.en.field_name" , "name": "translations.field_name"},
]
});
for more details refer django-rest-framework-datatables
& Django-parler-rest
The actual problem is that while making get request to server
data-table will add name value in column parameter so
instead of writing
"name": "translations.en.field_name"
write down:
"name": "translations.field_name"
remove language code

Identify if the post author is a page or a user?

What is the proper way to identify if the author of a post is a user or a page?
v2.8/OrangeESP/feed?fields=id,from{id,name,link}
"data": [
{
"id": "118067454874491_1584993008181921",
"from": {
"id": "1112315252115029",
"name": "Clara Barranquero",
"link": "https://www.facebook.com/app_scoped_user_id/1112315252115029/"
}
},
I currently use the "from.link" for that and if it is of form
https://www.facebook.com/app_scoped_user_id// then is a User
if it's of from
https://www.facebook.com/ then it is a Page
In v2.4 I could have included from{category} in the response and if that was not empty it meant the author is a Page.
Include a field that´s only available in the Page or User table:
https://developers.facebook.com/docs/graph-api/reference/page/
https://developers.facebook.com/docs/graph-api/reference/user/
Checking for app_scoped_user_id in the link field is not a bad idea though.

How to convert django variable into json in template properly

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.

Using the Django API

First of all, any help with this would be amazing! I am currently trying to learn Django and am also fairly new to Python. I am trying to create a simple project management web service that could communicate using JSON with another application. All it needs to do is:
Give a list of all projects.
Give a list of all tasks for each of the projects.
Allow users to submit time for a project and task.
For models I currently have a 'Project' model and 'Task' model. I have filled the database with some dummy information. My project model has variables id, name, and description. Task just has project, task_name.
My view for task 1 above is
def api(request):
projects = Project.objects.all()#.order_by('id')
projects = serializers.serialize('json', projects, indent=2)
return HttpResponse(projects, mimetype='application/json')
associated url is url(r'^api/project/$', 'project.views.api'),
However this outputs the text below when typing
http://127.0.0.1:8000/api/project/
into the browser. Is there a better way to test JSON output? I would rather it only output the 'id' and 'name'. For some reason the id doesn't even show. This is what I put for id in models id = models.AutoField(primary_key=True). It works in the interactive shell.
[
{
"pk": 1,
"model": "project.project",
"fields": {
"name": "Project One",
"description": "This is the description for project one"
}
},
{
"pk": 2,
"model": "project.project",
"fields": {
"name": "Project Two",
"description": "This is Project Two"
}
}
]
I learn by example so if someone could show me how this should be done I would be extremely grateful!
By the way for outputting the list of tasks, I was thinking the url would be something like:
http://127.0.0.1:8000/api/project/?project_name
but I'm not sure how to handle that in the view.