Reputation: 68
I want to fetch data from the model shown below. class ModelItem should return all the 4 values in the return statement.
class ModelItem(models.Model):
"""Stores item names for user"""
item_owner = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
item_name = models.TextField(max_length=100, null=True)
def __unicode__(self):
return "{0}, {1}, {2}, {3}".format(
self.pk,
self.item_owner.pk,
self.item_owner.username,
self.item_name,
)
At views.py the code below works.I get all the values that class 'ModelItem' is returning
user_id = 2
get_data = ModelItem.objects.filter(item_owner=user_id)
context = {'user_items': get_data}
return render(request, 'itemrequests.html', context)
Results this(pk of item, pk of item_owner, username of item_owner, item_name):
<QuerySet [<ModelItem: 1, 2, app_user, 2h-Axe>, <ModelItem: 2, 2, app_user, Ball of fire>]>
But if trying to return data in JSON (and therefore having to use .values() )
user_id = 2
get_data = ModelItem.objects.filter(item_owner=user_id).values()
return JsonResponse({'results': list(get_data)})
Results(username is missing):
{"results": [{"item_name": "2h-Axe", "item_owner_id": 2, "id": 1}, {"item_name": "Ball of fire", "item_owner_id": 2, "id": 2}]}
I can't find out what is causing this. Is it the way I am returning data from the model or something else?
SOLVED
Ok So in order to return customized data from model I switched from using Djangos default User-model to a custom User-model by adding this class to models.py:
class SiteUser(AbstractUser):
def natural_key(self):
return (self.username, self.pk)
For django to start using my new custom User-model I also added following into settings.py:
AUTH_USER_MODEL = 'homepage.SiteUser'
This way I am still using the default User-model as a base and just adding things to it. In this class I added the natural_key() -method which returns the username and primary key of an user.
In other models where I point Foreign Keys to User I made following change:
models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)
In my views.py I used then following:
user_id = 1
get_data = ModelItem.objects.select_related('item_owner').filter(item_owner=user_id)
ser_data = serializers.serialize("json", get_data, use_natural_foreign_keys=True)
return HttpResponse(ser_data, content_type="application/json")
Result:
[{"model": "homepage.modelitem", "pk": 1, "fields": {"item_owner": ["Murzum", 1], "item_name": "2h-Axe"}}, {"model": "homepage.modelitem", "pk": 2, "fields": {"item_owner": ["Murzum", 1], "item_name": "Ball Of fire"}}]
Now I have both username and pk values for the item_owner. Also learning now about django Manager interface
Upvotes: 0
Views: 78
Reputation: 261
Methods __unicode__
or __str__
are only for representation when you print an object, it doesn't means that if you return an instance will work in that way. You have to return the information you need serializing the data.
EDIT: Also you can use select_related method in order to avoid extra queries.
ModelItem.objects.select_related('item_owner').filter(item_owner=user_id)
Upvotes: 1