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
Related
I am trying load some data into datatables. I am trying to specify columns in the model.objects query by using .only() --- at first glance at the resulting QuerySet, it does in fact look like the mySQL query is only asking for those columns.
However, When I try to pass the QuerySet into Paginator, and/or a Serializer, the result has ALL columns in it.
I cannot use .values_list() because that does not return the nested objects that I need to have serialized as part of my specific column ask. I am not sure what is happening to my .only()
db_result_object = model.objects.prefetch_related().filter(qs).order_by(asc+sort_by).only(*columns_to_return)
paginated_results = Paginator(db_result_object,results_per_page)
serialized_results = serializer(paginated_results.object_list,many=True)
paginated_results.object_list = serialized_results.data
return paginated_results
This one has tripped me up too. In Django, calling only() doesn't return data equivalent to a SQL statement like this:
SELECT col_to_return_1, ... col_to_return_n
FROM appname_model
The reason it doesn't do it like this is because Django returns data to you not when you construct the QuerySet, but when you first access data from that QuerySet (see lazy QuerySets).
In the case of only() (a specific example of what is called a deferred field) you still get all of the fields like you normally would, but the difference is that it isn't completely loaded in from the database immediately. When you access the data, it will only load the fields included in the only statement. Some useful docs here.
My recommendation would be to write your Serializer so that it is only taking care of the one specific filed, likely using a SerializerMethodField with another serializer to serialize your related fields.
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.
I want to attach a field value (id) to a QS like below, but Django throws a 'str' object has no attribute 'lookup' error.
Book.objects.all().annotate(some_id='somerelation__id')
It seems I can get my id value using Sum()
Book.objects.all().annotate(something=Sum('somerelation__id'))
I'm wondering is there not a way to simply annotate raw field values to a QS? Using sum() in this case doesn't feel right.
There are at least three methods of accessing related objects in a queryset.
using Django's double underscore join syntax:
If you just want to use the field of a related object as a condition in your SQL query you can refer to the field field on the related object related_object with related_object__field. All possible lookup types are listed in the Django documentation under Field lookups.
Book.objects.filter(related_object__field=True)
using annotate with F():
You can populate an annotated field in a queryset by refering to the field with the F() object. F() represents the field of a model or an annotated field.
Book.objects.annotate(added_field=F("related_object__field"))
accessing object attributes:
Once the queryset is evaluated, you can access related objects through attributes on that object.
book = Book.objects.get(pk=1)
author = book.author.name # just one author, or…
authors = book.author_set.values("name") # several authors
This triggers an additional query unless you're making use of select_related().
My advice is to go with solution #2 as you're already halfway down that road and I think it'll give you exactly what you're asking for. The problem you're facing right now is that you did not specify a lookup type but instead you're passing a string (somerelation_id) Django doesn't know what to do with.
Also, the Django documentation on annotate() is pretty straight forward. You should look into that (again).
You have <somerelation>_id "by default". For example comment.user_id. It works because User has many Comments. But if Book has many Authors, what author_id supposed to be in this case?
what's the difference between using:
Blabla.objects.values('field1', 'field2', 'field3')
and
Blabla.objects.only('field1', 'field2', 'field3')
Assuming Blabla has the fields in your question, as well as field4,
Blabla.objects.only('field1', 'field2', 'field3')[0].field4
will return the value of that object's field4 (with a new database query to retrieve that info), whereas
Blabla.objects.values('field1', 'field2', 'field3')[0].field4
will give
AttributeError: 'dict' object has no attribute 'field4'
This is because .values() returns a QuerySet that returns dictionaries, which is essentially a list of dicts, rather than model instances (Blabla).
The answers given so far are correct, but they don't mention some of the differences in terms of queries. I will just report them.
.get()
# User.objects.get(email='user#email.com').username
SELECT "users_user"."id", "users_user"."password", "users_user"."last_login",
"users_user"."is_superuser", "users_user"."username", "users_user"."first_name",
"users_user"."last_name", "users_user"."email", "users_user"."is_staff", "users_user"."is_active",
"users_user"."date_joined", "users_user"."name"
FROM "users_user"
WHERE "users_user"."email" = 'user#email.com'; args=('user#email.com',)
.only().get()
# User.objects.only('username').get(email='user#email.com')
SELECT "users_user"."id", "users_user"."username"
FROM "users_user"
WHERE "users_user"."email" = 'user#email.com'; args=('user#email.com',)
.values().get()
# User.objects.values('username').get(email='user#email.com')
SELECT "users_user"."username"
FROM "users_user"
WHERE "users_user"."email" = 'user#email.com'; args=('user#email.com',)
As you can see, only() will also select the id of the record. This is probably because of the fact that it will output a model that you can later use, as the other answers mentioned.
.values() gives you "less than a model"; the items it returns are closer to dictionaries than full models, which means you don't get the model attributes but you also don't have to initialize full models.
.only() restricts the field list in the SQL to specific fields you care about, but still initializes a full model; it defers loading of the other fields until you access them (if at all).
values() returns QuerySet - which when iterated returns dictionaries representing the model. It does not return model objects.
only() is a way of restricting the columns returned, and ensuring that only those columns are returned immediately - which is why it is sometimes referred to as the opposite of defer() It is the equivalent of saying SELECT foo, bar, zoo FROM rather than the normal SELECT [all columns] FROM. It will return a QuerySet that can further be chained.
When I do this,
>>> b = Blog.objects.all()
>>> b
I get this:
>>>[<Blog: Blog Title>,<Blog: Blog Tile>]
When I query what type b is,
>>> type(b)
I get this:
>>> <class 'django.db.models.query.QuerySet'>
What does this mean? Is it a data type like dict, list, etc?
An example of how I can build data structure like a QuerySet will be appreciated.
I would want to know how Django builds that QuerySet (the gory details).
A django queryset is like its name says, basically a collection of (sql) queries, in your example above print(b.query) will show you the sql query generated from your django filter calls.
Since querysets are lazy, the database query isn't done immediately, but only when needed - when the queryset is evaluated. This happens for example if you call its __str__ method when you print it, if you would call list() on it, or, what happens mostly, you iterate over it (for post in b..). This lazyness should save you from doing unnecessary queries and also allows you to chain querysets and filters for example (you can filter a queryset as often as you want to).
Yes, it's just another type, built like every other type.
A QuerySet represents a collection of objects from your database. It can have zero, one or many filters. Filters narrow down the query results based on the given parameters. In SQL terms, a QuerySet equates to a SELECT statement, and a filter is a limiting clause such as WHERE or LIMIT.
https://docs.djangoproject.com/en/1.8/topics/db/queries/
A QuerySet is a list of objects of a given model, QuerySet allow you to read data from database