To UPDATE data in database using GET and FILTER
problem:
Why does
I have a Django model :
The
But when I do:
Solution:
try this solution
Using Filter
Filter :
1.It can store more than one result in the list.so where we want retrieve more than one data at same id there we use Filter.
2. It is Used as Where(like sql) in Django.
3.
4. if object is not found then it will not raise error.
Try out this when you use filter in ORM query to update.
or
Note: filter equal to where (in sql)
Filter give only one result whereas Get give one or more than one result depending upon the data in database which is to be found
Using Get
GET:
1. It is also same as Filter. It is also Used as Where(like sql) in Django. But It Cann't Store more than one result.
2.
3. if object is not found then it will raise error.
problem:
Why does
objects.filter
not updating the field but objects.get
works?I have a Django model :
class QuestionAnswer(models.Model):
question = models.ForeignKey(Question)
marks = models.FloatField(null=True)
graded = models.IntegerField()
Now in command line I do:
>>> qa = QuestionAnswer.objects.filter(pk=12345)
>>> qa[0].graded
0
>>> qa[0].graded = 1
>>> qa[0].save()
>>> qa = QuestionAnswer.objects.filter(pk=12345)
>>> qa.graded
0
graded
field is not updated.But when I do:
>>> qa = QuestionAnswer.objects.get(pk=12345)
>>> qa.graded
0
>>> qa.graded = 1
>>> qa.save()
>>> qa = QuestionAnswer.objects.get(pk=12345)
>>> qa.graded
1
Why does objects.filter
not updating the field but objects.get
works.Solution:
try this solution
>>> qs = QuestionAnswer.objects.filter(pk=12345)
>>> qa = qs[0]
>>> qa.graded
0
>>> qa.graded = 1
>>> qa.save()
>>> qa = QuestionAnswer.objects.filter(pk=12345)
>>> qa[0].graded
This should be 1
By using
qa[0]
, you're not actually modifying and saving the same object (even though they represent the same SQL data).
This is due to the fact that querysets are lazy: they only execute the sql query when you actually try to use the data that the queryset would return. The way slices work with querysets, the query is executed but the result will not be cached. This means that whenever you use
qa[0]
, a new query is executed, and that data is saved in a newly created model instance. What you are effectively doing is this:>>> qs = QuestionAnswer.objects.filter(pk=12345)
>>> qa1 = qs.get()
>>> qa1.graded
0
>>> qa2 = qs.get()
>>> qa2.graded = 1
>>> qa3 = qs.get()
>>> qa3.save()
It should be obvious that
qa1
, qa2
and qa3
are different instances of your model: while they have the same attribute values (as the represent the same database data), they are actually saved in different places in memory and are completely separate from each other. Changing the graded
attribute on qa2
will not in any way affect qa3
, so when qa3
is saved, the changes to qa2
won't be reflected in the changes in the database.
However, if you were to evaluate the entire queryset before slicing, all results would be cached, and the following would work:
>>> qs = QuestionAnswer.objects.filter(pk=12345)
>>> qs[0] is qs[0]
False # These are not the same objects in memory...
>>> bool(qs) # This forces evaluation of the entire queryset
True
>>> qs[0] is qs[0]
True # ... but these are!
>>> qs[0].graded
0
>>> qs[0].graded = 1
>>> qs[0].save()
>>> qs = QuestionAnswer.objects.filter(pk=12345)
>>> qs[0].graded
1
Filter :
1.It can store more than one result in the list.so where we want retrieve more than one data at same id there we use Filter.
2. It is Used as Where(like sql) in Django.
3.
filter
returns a QuerySet
(even though it looks like a list). In django, querysets are lazy which means they are evaluated only when needed.4. if object is not found then it will not raise error.
Try out this when you use filter in ORM query to update.
user = User.objects.filter(email = 'bhartirawat@gmail.com').update(is_email_verified=True)
or
In filter we have no need to save filter like user.save(). It automatically save the data in the database.user = User.objects.filter(email = 'bhartirawat@gmail.com')user = user[0]user.is_email_verified=True
Note: filter equal to where (in sql)
Filter give only one result whereas Get give one or more than one result depending upon the data in database which is to be found
Using Get
GET:
1. It is also same as Filter. It is also Used as Where(like sql) in Django. But It Cann't Store more than one result.
2.
get
returns the actual object which is not "lazy"; which is why your changes seem to be effected immediately3. if object is not found then it will raise error.
Django will complain if more than one item matches the get() query. In this case, it will raiseMultipleObjectsReturned, which again is an attribute of the model class itself.user = User.objects.get(email = 'bhartirawat@gmail.com')user.is_email_verified=Trueuser.save()
Limiting QuerySets¶
This is the equivalent of SQL’s LIMIT and OFFSET clauses.
For example, this returns the first 5 objects (LIMIT 5):
>>> Entry.objects.all()[:5]
This returns the sixth through tenth objects (OFFSET 5 LIMIT 5):
>>> Entry.objects.all()[5:10]
Negative indexing (i.e. Entry.objects.all()[-1]) is not supported.
Generally, slicing a QuerySet returns a new QuerySet – it doesn’t evaluate the query. An exception is if you use the “step” parameter of Python slice syntax. For example, this would actually execute the query in order to return a list of every second object of the first 10:
>>> Entry.objects.all()[:10:2]
To retrieve a single object rather than a list (e.g. SELECT foo FROM bar LIMIT 1), use a simple index instead of a slice. For example, this returns the first Entry in the database, after ordering entries alphabetically by headline:
>>> Entry.objects.order_by('headline')[0]
This is roughly equivalent to:
>>> Entry.objects.order_by('headline')[0:1].get()
Note, however, that the first of these will raise IndexError while the second will raise DoesNotExist if no objects match the given criteria. See get() for more details..
3. get_or_create
it return a tuple -->> (object, created)
object -->> where object is the retrieved or created object
created -->> created is a boolean specifying whether a new object was created.
This is meant as a shortcut to boilerplatish code. For example:
try: obj = Person.objects.get(first_name='John', last_name='Lennon')except Person.DoesNotExist: obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)) obj.save()
The above example can be rewritten using get_or_create() like so:
obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon',
defaults={'birthday': date(1940, 10, 9)})
important:
1. If an object is found, get_or_create() returns a tuple of that object and False.
3. If an object is not found, get_or_create() will instantiate and save a new object, returning a tuple of the new object and True.
4.The get_or_create() method has similar error behavior to create() when you’re using manually specified primary keys. If an object needs to be created and the key already exists in the database, an IntegrityError will be raised. see this in below example.
5. Finally, a word on using get_or_create() in Django views. Please make sure to use it only in POST requests unless you have a good reason not to. GET requests shouldn’t have any effect on data. Instead, use POST whenever a request to a page has a side effect on your data
6. The new object will be created roughly according to this algorithm:
params = {k: v for k, v in kwargs.items() if '__' not in k}
params.update(defaults)
obj = self.model(**params)
obj.save()
Example:
You can use get_or_create() through Book’s chapters field, but it only fetches inside the context of that book:
>>> book = Book.objects.create(title="Ulysses")
>>> book.chapters.get_or_create(title="Telemachus")
(<Chapter: Telemachus>, True)
>>> book.chapters.get_or_create(title="Telemachus")
(<Chapter: Telemachus>, False)
>>> Chapter.objects.create(title="Chapter 1")
<Chapter: Chapter 1>
>>> book.chapters.get_or_create(title="Chapter 1")
# Raises IntegrityError
This is happening because it’s trying to get or create “Chapter 1” through the book “Ulysses”, but it can’t do any of them: the relation can’t fetch that chapter because it isn’t related to that book, but it can’t create it either because title field should be unique.
Field lookups or django query in SQL
Field lookups are how you specify the meat of an SQL WHERE clause. They’re specified as keyword arguments to theQuerySet methods filter(), exclude() and get().
>>> Entry.objects.filter(pub_date__lte='2006-01-01')
translates (roughly) into the following SQL
select * from blog_entry where pub_date <= '2006-01-01';
>>> Entry.objects.get(headline__exact="Man bites dog")
SELECT * from blog_entry WHERE headline = 'Man bites dog';
No comments:
Post a Comment