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).
Related
I've the following model:
class Quiz(models.Model):
name = models.CharField(max_length=255)
month = models.DateField()
class Question(models.Model):
title = models.CharField(max_lenght=255)
category = models.CharField(max_length=255)
status = models.CharField(max_length=255, status=(('Pending', 'Pending'), ('Approved', 'Approved'))
class Contest(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
questions = models.ManyToManyField(Question, related_name='contest_questions')
Now I want to get list of quizes with all questions whose status=Pending?
Any help would be much appreciated!
Another approach is query directly from the M2M table using values_list():
quiz_ids = list(Contest.objects.filter(questions__status='Pending').values_list('quiz__id', flat=True))
quiz_query = Quiz.objects.filter(id__in=quiz_ids)
EDIT 22/01/2021
Thanks for advices in models naming.
Here is diagram of my database: https://dbdiagram.io/d/5fd0815c9a6c525a03ba5f6f?
As you can see in this diagram, I have simplyed as Customers_Orders is in fact a ternary relationship with models comments. I decided to use an 'declared' throught models for this ternary relationship
Do I realy need to add a ManyToMany fields in Orders?
I have a look at Django's doc example with person, group and membership (https://docs.djangoproject.com/fr/3.1/topics/db/models/) and a manytomany fiels is added only in Group model, not in Person model
I have 2 models (Customers and Orders) with a declared throught models (Customers_Orders) to manage manytomany relationship.
But I did'nt understand how to query to have :
for one Customer, all its orders: How many orders were made by each customer
for one Order, all its customers: How many customers were associated for each order
I have understood, I should do:
c = Customers.objects.get(customer_id=1)
c.CustomersOrders.all() but it failled AttributeError: 'Customers' object has no attribute 'CustomersOrdersComments'
class Customers(SafeDeleteModel):
customer_id = models.AutoField("Customer id", primary_key = True)
orders = models.ManyToManyField(Orders, through = Customers_Orders, related_name = "CustomersOrders")
created_at = models.DateTimeField("Date created", auto_now_add = True)
class Orders(SafeDeleteModel):
order_id = models.AutoField("Order id", primary_key = True)
created_at = models.DateTimeField("Date created", auto_now_add = True)
class Customers_Orders(SafeDeleteModel):
order = models.ForeignKey("Orders", on_delete = models.CASCADE)
customer = models.ForeignKey("Customers", on_delete = models.CASCADE)
You can do this - Given these models:
class Customer(models.Model):
name = models.CharField(max_length=30, default=None, blank=True, null=True)
orders = models.ManyToManyField("Order", through="CustomerOrder", related_name="orders")
created_at = models.DateTimeField(auto_now_add=True)
class Order(models.Model):
created_at = models.DateTimeField(auto_now_add = True)
customers = models.ManyToManyField(Customer, through="CustomerOrder", related_name="customers")
class CustomerOrder(models.Model):
order = models.ForeignKey("Order", on_delete = models.CASCADE)
customer = models.ForeignKey("Customer", on_delete = models.CASCADE)
customer = Customer.objects.first()
# Get count of their orders
customer_orders_count = customer.orders.all().count()
order = Order.objects.first()
# Get count of order's customers
order_customers_count = order.customers.all().count()
The docs explains this quite well:
https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_many/
In your case, that would be something like:
customer = Customers.objects.get(customer_id=1) # Fetch a specific customer from DB
customer_orders = customer.orders.all() # Return a QuerySet of all the orders related to a given `customer`
c.CustomersOrders.all() can't work, because CustomersOrders is the class name of your through model, and your Customers model does not have any CustomersOrders field.
I have a Django models where I have this :
class Patient(models.Model):
FirstName = models.CharField(max_length=264)
LastName = models.CharField(max_length=264)
Address = models.TextField(blank=True)
Telephone_no = models.CharField(max_length=100,blank=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,related_name='patients')
class UploadedImages(models.Model):
patient = models.ForeignKey(Patient,on_delete=models.CASCADE,related_name='images')
original = models.ImageField(upload_to = user_directory_path, validators=[validate_file_extension],verbose_name = 'Image')
enhanced = models.ImageField(upload_to=analyses_directory_path, blank=True)
segmented = models.ImageField(upload_to=analyses_directory_path, blank=True)
class Processed(models.Model):
uploaded_image = models.ForeignKey(UploadedImages,on_delete=models.CASCADE,related_name='processed')
pre_analysed = models.ImageField(upload_to=analyses_directory_path, blank=True)
analysedimage = models.ImageField(upload_to=analyses_directory_path, blank=True)
so I want to make queries based on the current user which is user = request.user this is possible in the patient model case as I can make Patient.objects.filter(user=user)
but i can't make it the other 2 models
is there any idea how I can do this?
I didn't add the user FK as I thought I wouldn't need it but now I do?
do i need to add it ? can I make a query without adding the field ?
If you want to query across relationships, Django has explicit syntax for that. For example, to get all the UploadedImage objects for a specific user, use UploadedImage.objects.filter(patient__user=user).
Patient.objects.filter(user=user) returns a queryset, to get patient by user, assuming one Patient has only one user:
patient = Patient.objects.filter(user=user).first()
then you can do:
uploaded_images = patients.images.all()
for image in uploaded_images:
processed = image.processed.all()
Good day!
I have 2 models and I am trying to get sql equivalent of : select * from both models where order=xx. Appreciate little assistance :)
class Orders(models.Model):
order_id = models.AutoField(primary_key=True)
created = models.DateTimeField(auto_now_add=True)
class ResourcePool(models.Model):
email = models.EmailField()
item_a = models.CharField()
item_b = models.CharField()
item_c = models.CharField()
order_id = models.ForeignKey(Orders)
Tried the following, but it does not inlude fields from 'Orders' model
ResourcePool.objects.filter(order_id__pk=26).values()
ResourcePool.objects.filter(order_id__pk=26).select_related().values()
ResourcePool.objects.filter(order_id__pk=26).values('orders__created','email','item_a',item_b','item_c')
try this
try this
order = Orders.objects.get(pk=26)
resource=ResourcePool.objects.filter(order_id=order.id).select_related()
And to obtain the data of "Orders"
id_order_pk26 = resource.order_id.order_id
created_pk26 = resource.order_id.created
I have the following models in Django:
class campaign(models.Model):
start_date = models.DateField('Start Date')
end_date = models.DateField('End Date')
description = models.CharField(max_length=500)
name = models.CharField(max_length=200)
active_start_time = models.TimeField()
active_end_time = models.TimeField()
last_updated = models.DateTimeField('Date updated',auto_now=True)
active = models.BooleanField(default=True)
client_id = models.ForeignKey('client',on_delete=models.PROTECT)
def __unicode__(self):
return u'%d | %s | %s' % (self.id,self.name, self.description)
class campaign_product(models.Model):
product_id = models.ForeignKey('product',on_delete=models.PROTECT)
last_updated = models.DateTimeField('Date updated',auto_now=True)
campaign_id = models.ForeignKey('campaign',on_delete=models.PROTECT)
class product(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=500)
sku = models.CharField(max_length=200,blank=True,null=True)
retail_price = models.DecimalField(decimal_places=2,max_digits=11)
discount_price = ((1,'Yes'),(0,'No'))
discounted_price = models.DecimalField(decimal_places=2,max_digits=11,blank=True,null=True)
category_id = models.ForeignKey('category',on_delete=models.PROTECT)
last_updated = models.DateTimeField('Date updated',auto_now=True)
active = models.BooleanField(default=True)
def __unicode__(self):
return u'%d | %s' % (self.id, self.name)
I also have the following serializer:
class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = campaign_product
fields = ('product_id', 'campaign_id')
And the following view set behavior in the urls.py file:
class campaignProductViewSet(viewsets.ModelViewSet):
queryset = campaign_product.objects.filter(campaign_id__start_date__lte=datetime.now(),campaign_id__end_date__gte=datetime.now(),campaign_id__active__exact=True)
serializer_class = campaignProductSerializer
My problem is I need to include the name field from the products model in my query results when for instance a request is made on http://127.0.0.1:8000/campaign_product/1/. Currenly this request returns only the product_id and the campaign_id. I tried making the serializer as follows:
class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = campaign_product
fields = ('product_id', 'campaign_id', 'product.name')
But then the service returns the following error:
Field name `product.name` is not valid for model `campaign_product`.
I event tried using product__name with and without quotes. Without quotes it tells me that there is no such variable, and with quotes it gives the is not valid for model error similar to the above. Heeelp! Getting this extra field is proving to be a pain :-(
What you want will need to look something more like this:
class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
product_name = serializers.CharField(source='product_id.name')
class Meta:
model = campaign_product
fields = ('product_id', 'campaign_id', 'product_name')
P.S. As an unrelated side note, it is generally a convention in Python code to name classes with CamelCase, such as Campaign, CampaignProduct, Product, and CampaignProductSerializer.
Edit: P.P.S. Originally, I had put written the product_name field with source='product.name'. This was actually due to me looking at the code too quickly and making assumptions based on Django conventions. Typically, with a Django ForeignKey, you would name the ForeignKey field after the model you are linking to, rather than explicitly naming it with _id. For example, the CampaignProduct model would typically be written with product = ForeignKey(...) and campaign = ForeignKey(...). In the background, Django will actually use product_id and campaign_id as the database field names. You also have access to those names on your model instances. But the product and campaign variables on your model instances actually return the objects which you are referring to. Hopefully that all makes sense.