django orm group by taking value from order by - django

query_set = query_set.values('event','cat_type').annotate(cat_count=Count('id')).order_by("event__slug", "cat_type")
when I execute the sql query it returns, ... GROUP BY event_id,cat_type,event.slug,cat_type.
My question is 1.)why it considers the value written in ordey_by as Group by condition??
2.) Values('event') ----> returns event_id not event obj but How I can get event obj?

.values
returns id not the object itslef.
To get the object you would have to use filter() or get()

Related

How to get and update Django object in one query?

To optimize a lot my database I would like to make as less as possible any query.
I'm trying to get an object, increment the field "count_limit" and make an If statement after on the Customer instance.
To achieve it I've made this query who worked well.
Customer.objects.filter(user=user).update(count_limit=F('count_limit') + 1)
So after this query, count_limit has been incremented by 1 as I wanted.
When I'm trying to get the Customer instance as a result of this query, it returns "1".
Is it possible to make both, update the instance and get it as a return object ?
Thanks a lot
The update() method will return the number of updated rows. If you are using Postgres, then you can use the returning clause with the raw query.
query = 'UPDATE customer SET count_limit=(customer.count_limit + 1) WHERE customer.user_id=%s returning *'
updated_obj = Customer.objects.raw(query, [user.id])
I don't know if this can be achieved by ORM, but suggestions will be appreciated.
Make sure that the table name in raw query is correct. If you haven't definer db_table in the meta class of your model, then by default it will be myapp_model.
And to prevent SQL injection, from the Docs:
Do not use string formatting on raw queries or quote placeholders in
your SQL strings!
Follow Docs on raw()
You are looking for F functions: https://docs.djangoproject.com/en/3.0/ref/models/expressions/#f-expressions
Example from their documentation how to increase a counter
from django.db.models import F
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()

How to get multiple objects of a model without using filter?

In Django 2.2, we can use filter() to get a QuerySet of created objects. Using list(), I can have a list of QuerySet.
In order to get an instance of a model I can use the function get(), for instance MyModel.objects.all().get(name__exact="John"). However, the get() function works only for finding a single object. If if finds 2 or more objects, it returns an exception: MultipleObjectsReturned get() returned more than one.
Since I need to process the multiple object of my model and its attributes, I would like to get a list of objects. Is it possible? For example, I want to create a list of ages from all objects with John in the attribute name.
If not, how can I access an attribute (e.g. age) of the returned QuerySet from the MyModel.objects.all().filter(name__exact="John")?
Thanks.
Use values:
instances = MyModel.objects.filter(name__exact="John")
ages = instances.values('id', 'age')
You'll get a list of dictionaries with keys id and age.

Comparign __exact and get()

What is the need of __exact query lookup if we can simply fetch data using get().
I mean what are the extra benefits of __exact in querysets ??
.get() is used to get a single instance. We use get when sure of single objects being returned by the queryset.
If multiple instances are present it will throw you an error on console:
get() returned more than one person -- it returned 2!
A typical get query for a Person model would be:
Person.objects.get(id=1)
However, __exact is used with a queryset as a parameter check. For example:
if we have a model Person, and you want to find all the person objects whose names are exactly = "Luv33preet".
Queryset for this would be:
Person.objects.filter(name__exact="Luv33preet")
I hope this helps!
Both are not comparable both have different uses
models.py -
class Model1.py():
name= models.CharField(max_length=1000,null=True)
views.py(Query) -
Model1.objects.get(name='RakeshRao') #retrieve single object
Model1.objects.get(name__exact='RakeshRao') #part of query same as 'LIKE' in SQL

How to get a particular attribute from queryset in Django in view?

I have a query like this:
file_s = Share.objects.filter(shared_user_id=log_id)
Now, I want to get the files_id attribute from file_s in Django view. How can I do that?
Use values() to get particular attribute which will return you list of dicts, like
file_s = Share.objects.filter(shared_user_id=log_id).values('files_id')
EDIT: If you want only one attribute then you can use flat=True to suggest to return just list of values. However, make sure in what order the list will be.
file_s = Share.objects.filter(shared_user_id=log_id).values_list('files_id', flat=True).order_by('id')
Your Share.objects.filter() call returns a Djagno QuerySet object which is not a single record, but an iterable of filtered objects from the database with each item being a Share instance. It's possible that your filter call will return more than one item.
You can iterate over the QuerySet using a loop such as:
for share in files_s:
print share.files_id
If you know that your query is only expected to return a single item, you could do:
share = Share.objects.get(shared_user_id=log_id)
which will return a single Share instance from which you can access the files_id attribute. An exception will be raised if the query would return anything other than 1 result.
If you want to get only the value from a single value QuerySet you can do:
file_s = Share.objects.filter(shared_user_id=log_id).values_list('files_id', flat=True).first()

Difference between Django's filter() and get() methods

What is the difference between
mymodel=model.objects.get(name='pol')
and
mymodel=model.objects.filter(name='pol')
The Django QuerySet docs are very clear on this:
get(**kwargs)¶
Returns the object matching the given
lookup parameters, which should be in
the format described in Field lookups.
get() raises MultipleObjectsReturned
if more than one object was found. The
MultipleObjectsReturned exception is
an attribute of the model class.
get() raises a DoesNotExist exception
if an object wasn't found for the
given parameters. This exception is
also an attribute of the model class.
filter(**kwargs)
Returns a new QuerySet containing objects that match the given lookup parameters.
Basically use get() when you want to get a single unique object, and filter() when you want to get all objects that match your lookup parameters.
Note that behind the scenes the django get() method runs the filter() method, but checks that the filter results set is exactly one record
Also, on a side note, assuming pol is not available:
if mymodel=model.objects.get(name='pol').exists()==False:
print "Pol does not exist"
you will get:
AttributeError: 'Model' object has no attribute 'exists'
but:
if mymodel=model.objects.filter(name='pol').exists()==False:
print "Pol does not exist"
you will get: Pol does not exist.
I.e. If you want to run some code depending on whether a single object can be found, use filter. For some reason exists() works on QuerySet but not the specific object returned with get.
get() returns an object that matches lookup criterion.
filter() returns a QuerySet that matche lookup criterion.
For example, the following
Entry.objects.filter(pub_date__year=2006)
is equivalent to
Entry.objects.all().filter(pub_date__year=2006)
which means filter() is slightly expensive operation if the model class has a large number of objects, whereas get() is direct approach.
source: Django making queries
Another difference:
Because 'get' returns an object, the method 'update' cannot be called on the object; except a model method (which shouldn't be done, to avoid overriding), was written.
However, querying with 'filter', gives you the ability to update a preferred record.
e.g: say a model; 'Product' exists in your app; then you could do thus:
old_product_name = Product.objects.filter(product_name="green-peas")
old_product_name.update(product_name="skewed-peas")
That of course, isn't possible when you query with 'get'.
Django's get and filter methods are commonly used by django models, and are distinguished here.
Define 2 models.
class Student(models.Model):
Name = models.CharField('name', max_length=15, default='')
Age = models.CharField('age', max_length=15, default='')
class Book(models.Model):
student = models.ForeignKey(Student)
A.django get method:
django's get method is to get a matching result from the database, return an object, if the record does not exist, it will report an error. For example, if there is a record in my database, the value of the record name is django123, I use student = Student . objects . get ( name = ’ django123 ’ ),
returns a record object, which you can view through student . _ _ dict _ _, which returns a dictionary form, {' key ' : valeus}, key is the field The name, while values ​​are the contents of the value.
Using the get method to query a record that does not exist in the database, the program will report an error.
For example: student = Student . objects . get ( name = ’ django ’ ), obviously this 'django ' does not exist in the database, it will report an error.
If you use django's get to get the data of the associated table, if the data of the key table is more than 2, it will report an error.
If there is a record in the student table:
d name age
1 python 24
Book table:
id student_id
1 1
2 1
student = Student.objects.get(name='python')
book = Book.objects.get(student)
The result will be reported because the book table has 2 records that match the student table.
Two.django filter method:
django's filter method is to get a matching result from the database, return a list of objects, if the record does not exist, it will return [ ].
If the database has a record, the value of the record name is python123, using student = Student . objects .filter ( name = ’ python123 ’ ). Returning student is a list of objects. It can be seen that student [ 0 ] is the same as the student returned by the get method above.
If you use django's get to get the data of the associated table, no matter how many records in the associated table, no error will be reported.
django In addition to the powerful model, forms and templates are also very powerful.
filter has the function of caching data. The first time you query the database and generate the cache, the next time you call the filter method, you can directly get the cached data, and the get method is directly queried every time in database.
mymodel=model.objects.get(name='pol')
# OR
mymodel=model.objects.filter(name='pol')
Case 1: Suppose we have only one record that matches the name field pol. 
get() will return on single objects whereas filter() will also return a single object in the list.
Case 2: Suppose we have more than one records that match the name field pol.
get() will raise MultipleObjectsReturned but in the case of filter(), it will return a list of objects.
Case 3: Suppose we have no record found that matches the name field pol.
get() raises a DoesNotExist exception but in the case of filter(), it will return an empty list.
if you know it's one object that matches your query, use "get". It will fail if it's more than one and gives the error like this
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 143, in get
return self.get_query_set().get(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 407, in get
(self.model._meta.object_name, num))
MultipleObjectsReturned: get() returned more than one Poll -- it returned 2!
Otherwise use "filter", which gives you a list of objects.
Model = Employee
Employee : name,age,loc
Get:
Employee.objects.get(id=1)
It will through error if given object is not there
Filter :
Employee.objects.filter(id=1)
]>
It will return empty Queryset if given object is not there