Raw SQL -> Django ORM Code: Query that returns all blog posts with most recent approved comment for a specific user - django

I'm working on a simple blog system. Here is my models.py file:
from django.contrib.auth.models import User
from django.db import models
class Comment(models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey('Post')
content = models.TextField()
approved = models.NullBooleanField()
class Meta:
ordering = ('-id',)
def __unicode__(self):
return u'Comment by %s' % self.user
class Post(models.Model):
user = models.ForeignKey(User)
title = models.CharField(max_length=200)
slug = models.CharField(max_length=50)
content = models.TextField()
class Meta:
ordering = ('title',)
def __unicode__(self):
return self.title
Here is some test data in a fixture which I've named testdata.json (the "some_author" user is a superuser and the password is "Stack Overflow"):
[
{
"pk": 1,
"model": "auth.user",
"fields": {
"username": "some_author",
"first_name": "Some",
"last_name": "Author",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": "2014-07-02T20:18:49Z",
"groups": [],
"user_permissions": [],
"password": "pbkdf2_sha256$12000$PTl1hfgcIGZy$/0w1jNMBuKi9zk11JXhoS5WrbMBUgMDkZAhEvNEelbs=",
"email": "some_author#example.com",
"date_joined": "2014-07-02T20:18:29Z"
}
},
{
"pk": 2,
"model": "auth.user",
"fields": {
"username": "some_reader",
"first_name": "Some",
"last_name": "Reader",
"is_active": true,
"is_superuser": false,
"is_staff": false,
"last_login": "2014-07-02T20:21:10Z",
"groups": [],
"user_permissions": [],
"password": "pbkdf2_sha256$12000$CtTGfFeOaRhd$oVR6zFSpK2qg1AZ4fgdBG/wt6Sr56dHsEIxFO99mHC8=",
"email": "some_reader#example.com",
"date_joined": "2014-07-02T20:21:10Z"
}
},
{
"pk": 3,
"model": "auth.user",
"fields": {
"username": "another_reader",
"first_name": "Another",
"last_name": "Reader",
"is_active": true,
"is_superuser": false,
"is_staff": false,
"last_login": "2014-07-02T20:21:34Z",
"groups": [],
"user_permissions": [],
"password": "pbkdf2_sha256$12000$ZPnmV7fVeie3$08H2vv3A8Py4E92+uVAIiEaeg8CAL5deTyNAZj1YJMs=",
"email": "another_reader#example.com",
"date_joined": "2014-07-02T20:21:34Z"
}
},
{
"pk": 1,
"model": "blog.comment",
"fields": {
"content": "Comment 1 of 1 on post 1: approved",
"post": 1,
"user": 2,
"approved": true
}
},
{
"pk": 2,
"model": "blog.comment",
"fields": {
"content": "Comment 1 of 1 on post 2: not approved",
"post": 2,
"user": 2,
"approved": false
}
},
{
"pk": 3,
"model": "blog.comment",
"fields": {
"content": "Comment 1 of 2 on post 3: approved",
"post": 3,
"user": 2,
"approved": true
}
},
{
"pk": 4,
"model": "blog.comment",
"fields": {
"content": "Comment 2 of 2 on post 3: not approved",
"post": 3,
"user": 2,
"approved": false
}
},
{
"pk": 5,
"model": "blog.comment",
"fields": {
"content": "Comment 1 of 2 on post 4: not approved",
"post": 4,
"user": 2,
"approved": false
}
},
{
"pk": 6,
"model": "blog.comment",
"fields": {
"content": "Comment 2 of 2 on post 4: approved",
"post": 4,
"user": 2,
"approved": true
}
},
{
"pk": 7,
"model": "blog.comment",
"fields": {
"content": "Comment 1 of 2 on post 5: approved",
"post": 5,
"user": 2,
"approved": true
}
},
{
"pk": 8,
"model": "blog.comment",
"fields": {
"content": "Comment 2 of 2 on post 5: approved",
"post": 5,
"user": 2,
"approved": true
}
},
{
"pk": 9,
"model": "blog.comment",
"fields": {
"content": "Comment 1 of 2 on post 6: not approved",
"post": 6,
"user": 2,
"approved": false
}
},
{
"pk": 10,
"model": "blog.comment",
"fields": {
"content": "Comment 2 of 2 on post 6: not approved",
"post": 6,
"user": 2,
"approved": false
}
},
{
"pk": 11,
"model": "blog.comment",
"fields": {
"content": "Comment 1 of 1 on post 7: approved",
"post": 7,
"user": 3,
"approved": true
}
},
{
"pk": 1,
"model": "blog.post",
"fields": {
"content": "First post",
"slug": "post-1",
"user": 1,
"title": "Post 1"
}
},
{
"pk": 2,
"model": "blog.post",
"fields": {
"content": "Second post",
"slug": "post-2",
"user": 1,
"title": "Post 2"
}
},
{
"pk": 3,
"model": "blog.post",
"fields": {
"content": "Third post",
"slug": "post-3",
"user": 1,
"title": "Post 3"
}
},
{
"pk": 4,
"model": "blog.post",
"fields": {
"content": "Fourth post",
"slug": "post-4",
"user": 1,
"title": "Post 4"
}
},
{
"pk": 5,
"model": "blog.post",
"fields": {
"content": "Fifth post",
"slug": "post-5",
"user": 1,
"title": "Post 5"
}
},
{
"pk": 6,
"model": "blog.post",
"fields": {
"content": "Sixth post",
"slug": "post-6",
"user": 1,
"title": "Post 6"
}
},
{
"pk": 7,
"model": "blog.post",
"fields": {
"content": "Seventh post",
"slug": "post-7",
"user": 1,
"title": "Post 7"
}
},
{
"pk": 8,
"model": "blog.post",
"fields": {
"content": "Eighth post",
"slug": "post-8",
"user": 1,
"title": "Post 8"
}
}
]
I'm trying to query the database for all of the blog posts along with each blog post's most recent comment that meets both of these two conditions:
The comment was made by "Some Reader" (user_id = 2)
The comment has been approved
I want the query to return all of the blog posts, even if they don't have a comment that meets the above two conditions. For the blog posts that don't have a comment that meets the above two conditions, the returned comment column should just be NULL. I have this working with raw SQL:
for p in Post.objects.raw(
'''
SELECT blog_post.id,
blog_post.title,
blog_comment.content
FROM blog_post
LEFT OUTER JOIN (SELECT post_id,
MAX(id) AS latest
FROM blog_comment
WHERE user_id = 2
AND approved = 1
GROUP BY post_id) AS x
ON x.post_id = blog_post.id
LEFT OUTER JOIN blog_comment
ON blog_comment.post_id = x.post_id
AND blog_comment.id = x.latest
ORDER BY blog_post.id;
'''
):
print '%s: %s' % (
p.title,
p.content,
)
The above code outputs this (which is what I want):
Post 1: Comment 1 of 1 on post 1: approved
Post 2: None
Post 3: Comment 1 of 2 on post 3: approved
Post 4: Comment 2 of 2 on post 4: approved
Post 5: Comment 2 of 2 on post 5: approved
Post 6: None
Post 7: None
Post 8: None
My question is this: is it possible to (efficiently) do this same thing, but without resorting to raw SQL? I like to avoid raw queries whenever possible.

You can't do it without raw sql inside django orm paradigm.
But you can do it with two queries to db:
from django.db.models import Max
posts = Post.objects.annotate(Max('comment_set__id'))
comments_cache = Comment.objects.filter(id__in= posts.values('id', flat=True))
comments_dict = dict([(item.id, item) for item in comments_cache])
for item in posts:
print post, comments_dict[item.id]
I often make complex queries and still can't find better way than get all data I need with few queries inside cache-object and than group it as I need.
Please don't use code like:
#get_comment: return self.comment_set.filter(user=user, approved=True).latest('id')
for post in Post.objects.all():
print post.get_comment(request.user)
It will produce len(posts) sql-queries to database. It's bad practice.

You want all posts, but comments should be the one that matches specified criteria otherwise None. For that you can add a method/property inPost` model to get recent comment the way you wanted.
Don't think there is good way of doing this with ORM.
Add following method in your model,
class Post(models.Model):
...
#your code
def get_comment(self, user):
comment = None
try:
comment = self.comment_set.filter(user=user, approved=True).latest('id')
except Comment.DoesNotExist:
comment = None #no comment matching criteria
return comment
From you view or other code, you can do
for post in Post.objects.all():
print post.get_comment(request.user)

Related

Group queryset by field

I am working with Django and Django REST framework. I have a model called Selection that contains field called category, when i query the model to send the result to the frontend i get it with the following structure:
[
{
"id": 1,
"category": "SHOES",
"products": 122,
"created_at": "2021-09-11",
},
{
"id": 2,
"category": "SHOES",
"products": 4,
"created_at": "2021-10-07",
},
{
"id": 3,
"category": "CLOTHES",
"products": 0,
"created_at": "2021-10-08",
},
]
I need to put the selections of the same category in an array and remove the grouped-by category, like this:
{
"SHOES": [
{
"id": 1,
"products": 122,
"created_at": "2021-09-11",
},
{
"id": 2,
"products": 4,
"created_at": "2021-10-07",
}
],
"CLOTHES": [
{
"id": 3,
"category": "CLOTHES",
"products": 0,
"created_at": "2021-10-08",
}
]
}
I considered to making it with Javascript in the frontend, but before i wanted to know if there's a way to do this from Django.
Yes, you need to do some customisation in your code.
Get all categories by using values_list('category', flat=True) with your queryset
Iterate through them filtering category one by one
response_list = []
categories = Selection.objects.values_list('category', flat=True)
for category in categories:
data = Selection.objects.filter(category=category)
data = {
category: SelectionSerializer(data, many=True).data,
}
response_list.append(data)

Django rest framework CRUD API for model with foriegn key elements

Okay so here I am with another problem I'm facing with Django. This time it's the REST framework.
I have a Model with Foreign Key dependencies in my project. I had to retrieve the foreign key field as an object, not just an ID field and was successful in that using Serializer Relations.
So my Serializer.py looks like:
class EventSerializer(serializers.ModelSerializer):
owner = EventUserSerializer(read_only=False)
severity = EventSeveritySerializer(read_only=False)
type = EventTypeSerializer(read_only=False)
cause = EventCauseSerializer(read_only=False)
subcause = EventSubcauseSerializer(read_only=False)
impact = EventImpactSerializer(read_only=False)
point_location = PointLocationSerializer(read_only=False)
class Meta:
model = models.Event
fields = ('id', 'description', 'owner', 'status',
'severity', 'type', 'cause', 'subcause', 'impact',
'is_public', 'occurrence_time', 'reporting_agency',
'estimated_duration', 'confirmed_timestamp',
'rejected_timestamp', 'closed_timestamp', 'point_location', )
Making a GET request, I get the result I wanted:
{
"meta": {
"count": 1,
"previous": null,
"next": null
},
"results": [
{
"id": 8,
"description": "test event 1",
"owner": {
"user": {
"id": 1,
"username": "venus",
"email": "venus.saini#ibigroup.com"
}
},
"status": "confirmed",
"severity": {
"id": 2,
"created": "2016-08-24T07:27:24.722000Z",
"modified": "2016-08-24T07:27:24.723000Z",
"name": "Severe",
"is_enabled": true,
"sortorder": 1
},
"type": {
"id": 2,
"created": "2016-08-24T07:27:45.203000Z",
"modified": "2016-08-24T07:27:45.204000Z",
"name": "Accident",
"event_category": "unplanned",
"sortorder": 2
},
"cause": {
"id": 2,
"created": "2016-08-24T07:28:16.088000Z",
"modified": "2016-08-24T07:28:16.092000Z",
"name": "Whether Conditions",
"sortorder": 3,
"event_type": 2
},
"subcause": {
"id": 2,
"created": "2016-08-24T07:28:28.475000Z",
"modified": "2016-08-24T07:28:28.478000Z",
"name": "Slippery",
"display_name": "Slippery",
"sortorder": 4,
"cause": 2
},
"impact": {
"id": 2,
"created": "2016-08-24T07:28:40.599000Z",
"modified": "2016-08-24T07:28:40.599000Z",
"name": "All Lanes Blocked",
"sortorder": 5
},
"is_public": false,
"occurrence_time": "2016-08-25T06:34:13Z",
"reporting_agency": "",
"estimated_duration": null,
"confirmed_timestamp": "2016-08-25T06:34:15Z",
"rejected_timestamp": "2016-08-25T06:34:16Z",
"closed_timestamp": "2016-08-25T06:34:18Z",
"point_location": {
"id": 2,
"created": "2016-08-24T07:18:03.017000Z",
"modified": "2016-08-24T07:18:03.018000Z",
"roadway_name": "Northbound",
"direction": "North",
"is_primary": false,
"cross_street_name": "test street 1",
"offset": "After",
"distance": 3,
"is_forward": false
}
}]
}
The problem I face is while using the POST request. I don't know how that would work so I found this link. It looks like it has the solution; I mean this is exactly what I want to accomplish [passing the ID of the foreign key element makes the object entry]. But I keep getting random errors like super(BaseSerializer, self).__init__(**kwargs) TypeError: __init__() got an unexpected keyword argument 'is_relation'.
Can somebody please guide me to how I should be doing it? I'm using Postman to test my APIs.
Thanks in advance.
EDIT: Using PUT/POST without the CustomSerializer gives me error 415:
{
"detail": "Unsupported media type \"text/plain;charset=UTF-8\" in request."
}

FieldDoesNotExist on loading Fixture

I'm trying to load a fixture called initial_data.json:
[{"pk": 1, "model": "contenttypes.contenttype", "fields": {"model": "logentry", "name": "log entry", "app_label": "admin"}}, {"pk": 2, "model": "contenttypes.contenttype", "fields": {"model": "permission", "name": "permission", "app_label": "auth"}}, {"pk": 3, "model": "contenttypes.contenttype", "fields": {"model": "group", "name": "group", "app_label": "auth"}}, {"pk": 4, "model": "contenttypes.contenttype", "fields": {"model": "user", "name": "user", "app_label": "auth"}}, {"pk": 5, "model": "contenttypes.contenttype", "fields": {"model": "contenttype", "name": "content type", "app_label": "contenttypes"}}, {"pk": 6, "model": "contenttypes.contenttype", "fields": {"model": "session", "name": "session", "app_label": "sessions"}}, {"pk": 7, "model": "contenttypes.contenttype", "fields": {"model": "tweet", "name": "tweet", "app_label": "tweeter"}}, {"pk": "2pwa7lb5legwb02jw2h76f1e70j2jmo7", "model": "sessions.session", "fields": {"expire_date": "2014-09-14T00:20:41.773Z", "session_data": "OWQ4MmE3ZGRkZjliOWY3OTQ5OTdiMDIyYjE5ZWMwNmUwZTAyMThhMjp7Il9hdXRoX3VzZXJfYmFja2VuZCI6ImRqYW5nby5jb250cmliLmF1dGguYmFja2VuZHMuTW9kZWxCYWNrZW5kIiwiX2F1dGhfdXNlcl9pZCI6MX0="}}, {"pk": "ncl522f8kc6bf242chahmc2squtioirb", "model": "sessions.session", "fields": {"expire_date": "2014-09-14T01:19:42.407Z", "session_data": "NjY0NjliYjNkNDk0ODJhYWRjMDk5MjNjODA1NTAxYWIzZjg3ZGFkYzp7fQ=="}}, {"pk": 1, "model": "auth.permission", "fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 1}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 1}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 1}}, {"pk": 4, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 2}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 2}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 2}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 3}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 3}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 3}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 4}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 4}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 4}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 5}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 5}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 5}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 6}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 6}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 6}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "add_tweet", "name": "Can add tweet", "content_type": 7}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "change_tweet", "name": "Can change tweet", "content_type": 7}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "delete_tweet", "name": "Can delete tweet", "content_type": 7}}, {"pk": 1, "model": "auth.user", "fields": {"username": "nina", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2014-08-31T00:20:41.771Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$2LSBfxYO9fJJ$UT/BLyRLwBQIOUtOfA2aKkGw+xe44ZNYD2TWXqXoT3E=", "email": "", "date_joined": "2014-08-30T18:10:53.539Z"}}, {"pk": 2, "model": "auth.user", "fields": {"username": "admin", "first_name": "Admin", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2014-08-31T00:22:38Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$6JY3bvlplRf0$Rm6rcK9M3LNuTw1uZ3B/Je7rq420UCaf2iwmY8pIv2U=", "email": "admin#admin.com", "date_joined": "2014-08-31T00:22:38Z"}}, {"pk": 3, "model": "auth.user", "fields": {"username": "bob", "first_name": "Bob", "last_name": "Bobman", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2014-08-31T00:23:06Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$ehuPT7BoKVpF$VZTxDeaHtLG7jU4wQ1erlFciwMk7l8aCp9MIjSVa/NU=", "email": "bob#bob.com", "date_joined": "2014-08-31T00:23:06Z"}}, {"pk": 4, "model": "auth.user", "fields": {"username": "amy", "first_name": "Amy", "last_name": "Smith", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2014-08-31T00:23:24Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$Tv4vWeWICkfS$qcMP+xddceQZMVjHbdOhOsV6LKOQntKOkiaqdEzS2p8=", "email": "amy#smith.com", "date_joined": "2014-08-31T00:23:24Z"}}, {"pk": 1, "model": "tweeter.tweet", "fields": {"text": "I'm an Admin! ", "user": 2, "timestamp": "2014-08-30T18:51:04Z"}}, {"pk": 2, "model": "tweeter.tweet", "fields": {"text": "Bob is the coolest name EVAR", "user": 3, "timestamp": "2014-08-29T18:51:19Z"}}, {"pk": 3, "model": "tweeter.tweet", "fields": {"text": "I <3 Tweeter", "user": 4, "timestamp": "2014-08-30T15:52:09Z"}}, {"pk": 1, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-31T00:22:38.417Z", "object_repr": "Admin", "object_id": "2", "change_message": "", "user": 1, "content_type": 4}}, {"pk": 2, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-31T00:22:57.048Z", "object_repr": "Admin", "object_id": "2", "change_message": "Changed first_name, email, is_staff and is_superuser.", "user": 1, "content_type": 4}}, {"pk": 3, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-31T00:23:06.858Z", "object_repr": "Bob", "object_id": "3", "change_message": "", "user": 1, "content_type": 4}}, {"pk": 4, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-31T00:23:17.098Z", "object_repr": "Bob", "object_id": "3", "change_message": "Changed first_name, last_name and email.", "user": 1, "content_type": 4}}, {"pk": 5, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-31T00:23:24.481Z", "object_repr": "Amy", "object_id": "4", "change_message": "", "user": 1, "content_type": 4}}, {"pk": 6, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-31T00:23:35.860Z", "object_repr": "Amy", "object_id": "4", "change_message": "Changed first_name, last_name and email.", "user": 1, "content_type": 4}}, {"pk": 7, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-31T00:51:05.451Z", "object_repr": "I'm an Admin! ", "object_id": "1", "change_message": "", "user": 1, "content_type": 7}}, {"pk": 8, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-31T00:51:26.097Z", "object_repr": "Bob is the coolest name EVAR", "object_id": "2", "change_message": "", "user": 1, "content_type": 7}}, {"pk": 9, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-31T00:52:12.916Z", "object_repr": "I <3 Tweeter", "object_id": "3", "change_message": "", "user": 1, "content_type": 7}}, {"pk": 10, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-31T01:06:18.846Z", "object_repr": "admin", "object_id": "2", "change_message": "Changed username.", "user": 1, "content_type": 4}}, {"pk": 11, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-31T01:06:26.076Z", "object_repr": "bob", "object_id": "3", "change_message": "Changed username.", "user": 1, "content_type": 4}}, {"pk": 12, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-31T01:06:34.096Z", "object_repr": "amy", "object_id": "4", "change_message": "Changed username.", "user": 1, "content_type": 4}}]
But I get the following error when I'm running syncdb or using load data:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/base.py", line 393, in run_from_argv
self.execute(*args, **cmd_options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/base.py", line 444, in execute
output = self.handle(*args, **options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/commands/syncdb.py", line 25, in handle
call_command("migrate", **options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 120, in call_command
return command.execute(*args, **defaults)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/base.py", line 444, in execute
output = self.handle(*args, **options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 179, in handle
created_models = self.sync_apps(connection, executor.loader.unmigrated_apps)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 364, in sync_apps
hide_empty=True,
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 120, in call_command
return command.execute(*args, **defaults)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/base.py", line 444, in execute
output = self.handle(*args, **options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 60, in handle
self.loaddata(fixture_labels)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 90, in loaddata
self.load_label(fixture_label)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 141, in load_label
for obj in objects:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/serializers/json.py", line 84, in Deserializer
six.reraise(DeserializationError, DeserializationError(e), sys.exc_info()[2])
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/serializers/json.py", line 78, in Deserializer
for obj in PythonDeserializer(objects, **options):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/serializers/python.py", line 120, in Deserializer
field = Model._meta.get_field(field_name)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/options.py", line 554, in get_field
raise FieldDoesNotExist('%s has no field named %r' % (self.object_name, field_name))
django.core.serializers.base.DeserializationError: Problem installing fixture '/Users/wrb473/Documents/workspace/angulardjango/tweeter/fixtures/initial_data.json': ContentType has no field named u'name'
Where is the problem with the fixture?
On this page: https://docs.djangoproject.com/en/1.8/ref/contrib/contenttypes/#django.contrib.contenttypes.models.ContentType
"Changed in Django 1.8:
Before Django 1.8, the name property was a real field on the ContentType model." -- implies that as of 1.8 it's not a real field. Are you using 1.8? And if you remove name from your ContentType fixtures does it work?
This is because ContentType.name is a property and not a Field.
An excerpt from ContentType model definition:
class ContentType(models.Model):
app_label = models.CharField(max_length=100)
model = models.CharField(_('python model class name'), max_length=100)
objects = ContentTypeManager()
# ...
#property
def name(self):
# ...
The only fields defined on this model are app_label and model.
This means that code that serialized your objects has also included the property, whose value cannot be set when deserializing.
You can try removing anything that is not a model Field (in your case it is only name) from data on serialization.

how to use backward relation in django tastypie

this is my model
class Nisit(models.Model):
and this
class Page(models.Model):
followingNisit = models.ManyToManyField(Nisit,blank=True)
this is my resource
class NisitResource(ModelResource):
page = fields.ToManyField('chula.api.PageResource','page_set',null=True)
class Meta:
queryset = Nisit.objects.all()
resource_name = 'nisit'
filtering = {
'page' : ALL_WITH_RELATIONS,
'id' : ALL,
}
class PageResource(ModelResource):
followingNisit = fields.ToManyField(NisitResource, 'followingNisit',null=True)
reporter = fields.ManyToManyField(ReporterResource,'reporter')
followers_count = fields.CharField(attribute='followers_count')
class Meta:
queryset = Page.objects.all()
resource_name = 'page'
authorization= Authorization()
filtering = {
'id':ALL,
'followingNisit': ALL_WITH_RELATIONS,
}
It's ok when I request -------127.0.0.1:8000/api/v2/page/?format=json&followingNisit__id=1
But In the opposite way ,when i request ---------127.0.0.1:8000/api/v2/nisit/?format=json&page__id=1, I will get this error
{"error_message": "Cannot resolve keyword 'page_set' into field. Choices are: displayName, facebook, faculty, friend, id, major, n_id, name, page, password, picture, reporter, year_in_school", "traceback": "Traceback (most recent call last):\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 202, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 441, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 474, in dispatch\n response = method(request, **kwargs)\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 1127, in get_list\n objects = self.obj_get_list(request=request, **self.remove_api_resource_names(kwargs))\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 1890, in obj_get_list\n base_object_list = self.apply_filters(request, applicable_filters)\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 1862, in apply_filters\n return self.get_object_list(request).filter(**applicable_filters)\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\query.py\", line 624, in filter\n return self._filter_or_exclude(False, *args, **kwargs)\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\query.py\", line 642, in _filter_or_exclude\n clone.query.add_q(Q(*args, **kwargs))\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\sql\\query.py\", line 1250, in add_q\n can_reuse=used_aliases, force_having=force_having)\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\sql\\query.py\", line 1122, in add_filter\n process_extras=process_extras)\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\sql\\query.py\", line 1316, in setup_joins\n \"Choices are: %s\" % (name, \", \".join(names)))\n\nFieldError: Cannot resolve keyword 'page_set' into field. Choices are: displayName, facebook, faculty, friend, id, major, n_id, name, page, password, picture, reporter, year_in_school\n"}
I have also been struggling with the same FieldError thrown from setup_joins, and I think I just solved my issue. I was trying to filter through a Many-to-Many relationship, and could never get the "_set" in fields.ToManyField() to work. After debugging the TastyPie code in the error case and in a working simple filter, I realized it may be possible to bypass the need for the intermediary resource altogether.
Here is what worked for me, I hope it helps in your situation. Since I don't know your model setup, I'll make up a similar example.
First, the models:
### models.py ###
from django.db import models
class Ingredient(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
def __unicode__(self):
return '%s' % (self.name)
class RecipeIngredient(models.Model):
recipe = models.ForeignKey('Recipe')
ingredient = models.ForeignKey('Ingredient')
weight = models.IntegerField(null = True, blank = True)
def __unicode__(self):
return '%s: %s' % (self.recipe, self.ingredient)
class Recipe(models.Model):
title = models.CharField(max_length=100)
ingredients = models.ManyToManyField(Ingredient, through='RecipeIngredient')
def __unicode__(self):
return '%s' % (self.title)
And here are the ModelResources:
### api.py ###
from tastypie.resources import ModelResource, ALL, ALL_WITH_RELATIONS
from tastypie import fields
from some_app.models import Ingredient, Recipe
class IngredientResource(ModelResource):
class Meta:
queryset = Ingredient.objects.all()
resource_name = 'ingredient'
filtering = {
'name': ALL,
}
class RecipeResource(ModelResource):
ingredients = fields.ToManyField(
'some_app.api.IngredientResource',
'ingredients',
full=True)
class Meta:
queryset = Recipe.objects.all()
resource_name = 'recipe'
filtering = {
'title': ALL,
'ingredients': ALL_WITH_RELATIONS,
}
Notice I do not have a RecipeIngredientResource, I hook directly to the IngredientResource, which works because the Recipe model includes the ManyToManyField ingredients with the option through='RecipeIngredient'
An example URL to filter all recipes for a particular ingredient then looks like:
http://localhost:8000/api/recipes/recipe/?ingredients__name=blueberry
And, for completeness, here's a fixture for a Django app named 'some_app' to save time entering data for anyone wanting to implement this example:
[
{
"pk": 1,
"model": "some_app.ingredient",
"fields": {
"name": "apple",
"description": "a tempting fruit"
}
},
{
"pk": 2,
"model": "some_app.ingredient",
"fields": {
"name": "cherry",
"description": "a red fruit"
}
},
{
"pk": 3,
"model": "some_app.ingredient",
"fields": {
"name": "blueberry",
"description": "a blue fruit"
}
},
{
"pk": 4,
"model": "some_app.ingredient",
"fields": {
"name": "flour",
"description": "used for baking and stuff"
}
},
{
"pk": 5,
"model": "some_app.ingredient",
"fields": {
"name": "sugar",
"description": "makes stuff sweet"
}
},
{
"pk": 1,
"model": "some_app.recipeingredient",
"fields": {
"recipe": 1,
"weight": 3,
"ingredient": 1
}
},
{
"pk": 2,
"model": "some_app.recipeingredient",
"fields": {
"recipe": 1,
"weight": 2,
"ingredient": 4
}
},
{
"pk": 3,
"model": "some_app.recipeingredient",
"fields": {
"recipe": 1,
"weight": 4,
"ingredient": 5
}
},
{
"pk": 4,
"model": "some_app.recipeingredient",
"fields": {
"recipe": 2,
"weight": 8,
"ingredient": 2
}
},
{
"pk": 5,
"model": "some_app.recipeingredient",
"fields": {
"recipe": 2,
"weight": 4,
"ingredient": 4
}
},
{
"pk": 6,
"model": "some_app.recipeingredient",
"fields": {
"recipe": 2,
"weight": 6,
"ingredient": 5
}
},
{
"pk": 7,
"model": "some_app.recipeingredient",
"fields": {
"recipe": 3,
"weight": 15,
"ingredient": 3
}
},
{
"pk": 8,
"model": "some_app.recipeingredient",
"fields": {
"recipe": 3,
"weight": 5,
"ingredient": 4
}
},
{
"pk": 9,
"model": "some_app.recipeingredient",
"fields": {
"recipe": 3,
"weight": 6,
"ingredient": 5
}
},
{
"pk": 1,
"model": "some_app.recipe",
"fields": {
"title": "Apple Pie"
}
},
{
"pk": 2,
"model": "some_app.recipe",
"fields": {
"title": "Cherry Pie"
}
},
{
"pk": 3,
"model": "some_app.recipe",
"fields": {
"title": "Blueberry Pie"
}
}
]
This is the thing, if django tastypie works very similar to django (as anyone could expect) you are using a bad keyword, in you case, It wouldn't be page_set, use just page instead and it will work.
I recommend to you using a plural in the field name
pages = fields.ToManyField('chula.api.PageResource','page_set',null=True)
so the forward relation is pages and the backward relation is page_set I cant remember which now. But anyway it will look nicer.

django-piston: how to add an entity field to manyToMany related entity fields?

I have two Entities: Post and Tag, with a ManyToMany relation called 'tagged'
What I need to do, in order to parse json returned on particular client, is output fields by adding a field 'postID' (the pk field of current Post) to Tag related to that post.
So, my output now is:
{
"post": {
"name": "Dummy name",
"pk": 1,
"tags": [
{
"id": 2,
"name": "Patio"
},
{
"id": 3,
"name": "Roof"
}
],
"ref": "709230056"
}
},
but it should be:
{
"post": {
"name": "Dummy name",
"pk": 1,
"tags": [
{
"id": 2,
"name": "Patio",
"postID": 1,
},
{
"id": 3,
"name": "Roof"
"postID": 1,
}
],
"ref": "709230056"
}
},
I've alrady tried to play with fields of my Handler but with no success :(
How to do that ?
Thanks