Problem with response values with join in django query? - django

i have this models.
class Product(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=50)
PublicationDate = models.DateField()
trend = models.IntegerField()
class User_list(models.Model):
product_id = ForeignKey(Product, on_delete=models.CASCADE)
userid = models.IntegerField()
i make a join query with select related
data = User_list.objects.select_related('product_id')
but the response don't get me Product fields value.
it's get me only User_list values, like this
"[{\"model\": \"app.user_list\", \"pk\": 1, \"fields\": {\"product_id\": 11916, \"userid\": 9}}]"
What's the problem?

Related

Django - How to reach relational field

I have Patient model which has many to many relation with ICF model. ICF model has many to one field to Unite model. In Unite model I have Unite names. I want to reach Unite names that are assigned to Patient with relations. I try to reach Unite names for each Patient. If it is more than one I cannot list them for that person. Here are my codes.
This is my patient model.
class Patient (models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
lastname = models.CharField(max_length=255, default="doe")
data = models.JSONField()
Intensivecare_form = models.ManyToManyField(Intensivecare_Form)
isDeleted = models.BooleanField(default=False)
This is my ICF model.
class Intensivecare_Form (models.Model):
id = models.AutoField(primary_key=True)
hospitals_id = models.ForeignKey(Hospital, on_delete=models.CASCADE)
formname = models.CharField(max_length=128)
data = models.JSONField()
unites_id = models.ForeignKey(Unite, on_delete=models.CASCADE)
At last, This is my Unite model
class Unite (models.Model):
id = models.AutoField(primary_key=True)
unitename = models.CharField(max_length=128)
In my views.py file I have a function as below
def listPatients(request):
Patients = Patient.objects.all()
output = []
for patient in Patients:
unitename = []
icfinfo = serializers.serialize('json', patient.Intensivecare_form.all())
jsonicfinfo = json.loads(icfinfo)
unitename.append(jsonicfinfo)
output.append({'id': patient.id,
'fname': patient.name,
'lname': patient.lastname,
'data': patient.data,
'unitename': unitename,
})
return JsonResponse(output, safe=False)
This is what output looks like. I need to reach formname in unitename
0-> id, fname..., unitename-> 0 -> fields -> unitename
It seems your ICForm is only pointing at one Unite object.
Maybe try this to get all ICForm's in the query.
Instead of
unitename = []
icfinfo = serializers.serialize('json', patient.Intensivecare_form.all())
jsonicfinfo = json.loads(icfinfo)
unitename.append(jsonicfinfo)
Try renaming Intensivecare_form model rename unites_id to unites -- django knows to link on the id automatically and calling it unites_id could cause naming conflicts
Intensivecare_Form(models.Model):
unites = models.ForeignKey(Unites, on_delete=models.CASCADE)
And to get all unites names just get it in one query
unite_names = list(patient.Intensivecare_form.all().values_list('unites__unitename', flat=True))
That should do it for you! Best of luck!

How to Retrieve a specific value of a Tuple from Django database

So here I have a table named Product which contains Food name,Category,Price,Image,Dataset id column so i would like to retrieve the value of Dataset id only ,in Django
I would like to put parse dataset_id into recommend function but it doesnt give value of 31 while i select Pizza so i tried just printing it and the output in my console is <django.db.models.query_utils.DeferredAttribute object at 0x03B11CE8>
here is my code from views.py
from .models import Product
def cart(request):
if request.user.is_authenticated:
print(Product.dataset_id)
res=recommend(item_id=31, num=3)
customer = request.user.customer
order , created = Order.objects.get_or_create(customer = customer , complete=False)
items = order.orderitem_set.all()
cartItems = order.get_cart_items
print(res)
Here is my code for Products in models.py
class Product(models.Model):
food_id = models.AutoField
food_name = models.CharField(max_length=50, default="")
cateory = models.CharField(max_length=50, default="")
subcategory = models.CharField(max_length=50, default="")
price = models.IntegerField(default=0)
image = models.ImageField(upload_to='menu/images', default="")
dataset_id = models.IntegerField(default = 0)
You need to first get the Product whose dataset_id you want to print.
You can do that by using pk value or any other unique attributes.
i.e : product = Product.objects.get(pk=pk)
print(product.dataset_id)

How to represent join queries in Django?

How do we present sql query like this one in django?
select * from question LEFT JOIN (select * from question_solved where username = 'ashu'
) AS result on question.q_id = result.q_id
I tried to perform query separately,
q = question_solved.objects.filter(username='ashu')
y = Question.objects.filter(q__q_id = Question.q_id)
But it is giving me error
django.core.exceptions.FieldError: Cannot resolve keyword 'q' into field. Choices are: q_answer, q_content, q_id, q_submission, q_tags, q_title, q_type
my model file
from django.db import models
# Create your models here.
class Question(models.Model):
q_id = models.CharField(primary_key=True, max_length=20)
#q_difficulty = models.IntegerField()
q_title = models.CharField(max_length = 200)
q_content = models.CharField(max_length = 1000)
q_type = models.IntegerField()
q_answer = models.FloatField()
q_submission = models.IntegerField()
q_tags = models.CharField(max_length=10)
class Student(models.Model):
username = models.CharField(primary_key=True, max_length=30)
password = models.CharField(max_length=200)
class question_solved(models.Model):
q_id = models.CharField(primary_key=True, max_length=20)
username = models.CharField(max_length=30)
Query will produce result like this.
Thanks in advance.
You should use ForeignKey to relate models .
From what I understood you want to get all the questions solved by username ashu.
In your current state of models you can do this like:
First get a list of q_id values that are in the table for username ashu. you can do that using values_list():
quest=question_solved.objects.filter(username='ashu').values_list('q_id',flat=True)
Then from the Question table filter the objects with q_id in the list obtained from previous query.
solved_questions=Question.objects.filter(q_id__in=quest)
You can get all the question with all()
all_questions = Question.objects.all()
and if you want you can have 2 separate queryset one which is a list of question solved by 'ashuand other which is not solved byashu`.
unsolved_questions=Question.objects.exclude(q_id__in=quest).

count(*) as in Django Orm

I find this, but I need something like
select count(*) as my_count from my_table;
Its possible in Django?
Thanks.
For example if you have "Book" object just cast .count() method:
Book.objects.count()
Suppose you want to do an aggregation. Django ORM can do it. Here is a documentation.
In short, you can aggregate some count and then use it in you query. Example from documentation:
class Author(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
class Publisher(models.Model):
name = models.CharField(max_length=300)
num_awards = models.IntegerField()
class Book(models.Model):
name = models.CharField(max_length=300)
pages = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
rating = models.FloatField()
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
pubdate = models.DateField()
class Store(models.Model):
name = models.CharField(max_length=300)
books = models.ManyToManyField(Book)
registered_users = models.PositiveIntegerField()
Now, when you do this:
>>> from django.db.models import Count
>>> pubs = Publisher.objects.annotate(num_books=Count('book'))
>>> pubs
SQL query will be the following:
SELECT "main_publisher"."id", "main_publisher"."name", "main_publisher"."num_awards", COUNT("main_book"."id") AS "num_books" FROM "main_publisher"LEFT OUTER JOIN "main_book" ON ("main_publisher"."id" = "main_book"."publisher_id") GROUP BY "main_publisher"."id", "main_publisher"."name", "main_publisher"."num_awards" LIMIT 21; args=()
And you can use aggregated data in filtering:
>>> pubs = Publisher.objects.annotate(num_books=Count('book')).filter(num_books=2)
>>> pubs
SELECT "main_publisher"."id", "main_publisher"."name", "main_publisher"."num_awards", COUNT("main_book"."id") AS "num_books" FROM "main_publisher"LEFT OUTER JOIN "main_book" ON ("main_publisher"."id" = "main_book"."publisher_id") GROUP BY "main_publisher"."id", "main_publisher"."name", "main_publisher"."num_awards" HAVING COUNT("main_book"."id") = 2 LIMIT 21; args=(2,)

Django Query: join a table 2 times

I have 2 tables:
Product(id, name)
Attribute(id, product_id, name, value)
How can I join the table "Attribute" 2 times when searching products? They must be in one query because of paging later.
An example: Search products which must have 2 attributes - one for name=att1, value=value1 and another for name=att2, value=value2.
Source Code:
class Product(models.Model):
product_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, null=False)
class Attribute(models.Model):
attribute_id = models.AutoField(primary_key=True)
product = models.ForeignKey(Product, null=False)
name = models.CharField(max_length=100, null=False)
value = models.CharField(max_length=100, null=False)
A query that not working:
Product.objects.select_related().filter('attribute__name': 'n1', 'attribute__value':'v1').filter('attribute__name': 'n2', 'attribute__value':'v2')
You don't need to join them 2 times. You can create a model with ForignKey then get the set of relate attribute
For example :
you create model like this
class Product(models.Model):
name = models.CharField(max_length=100)
class Attribute(models.Model):
product = models.ForeignKey(Product)
name = models.CharField(max_length=100)
value = models.IntegerField()
You can get product item by call
item = Product.objects.get(id=xxx)
Then get all list of attribute relate to this item
from django.db.models import Q
attr = item.attribute_set.filter(Q(name='name1') | Q(name='name2'))
Use something like this:
p = Product.objects.get(pk=1)
filtered = p.attribute_set.filter(name__in=['n1','n2'],value__in=['v1','v2'])