Im a newbie to Django and would like to understand what is the difference between filter vs get
Get
Entry.objects.get(id__exact=14)
Filter
Entry.objects.filter(id__exact=14)
What difference the above statement makes?
Thanks in advance.
the get only brings an element that is equal to what you're looking for but the filter brings everything related to that item you want.
filter returns many things found.
get returns only one thing to what you're looking for
for example:
GET
Task.objects.get(id=1,status=1)
Filter
Groups.objects.filter(user=1)
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
__data = User.objects.get(is_active=1).exclude(id=id)
Error:get() returned more than one User -- it returned 19!,
Type:<class 'django.contrib.auth.models.MultipleObjectsReturned'>
------successful-------
__data = User.objects.filter(is_active=1).exclude(id=id)
-------successful------
Check the Link
To add to what others have said... (get returns exactly 1 record, while filter returns a set), an important thing to note is the type of the results.
get() returns an object, while filter returns a queryset type. This means you can do something like
age = User.objects.get(name="Ryan").age
Whereas if you were using filter, you'd need to do a couple extra steps:
ages = User.Objects.filter(name="ryan").values('age')
for user_age in users:
print(user_age)
The important thing to note is that filter returns an iterable type with a values() method dictating which fields you want. Get simply returns an object with the fields as attributes, so it is much simpler to get the data you need.
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.
Related
I have some ruby code from my Ruby on Rails project.
I am formatting some data so I am calling attributes.extract! to get the fields I need from my model.
I noticed recently that every now and then the data wouldn't get extracted as expected. I realized that I needed a splat operator. But it is strange because I do notice that sometimes when the method is called in my Rails project it will sometimes extract the data without the use of the splat operator. But when I run the code from my Rails console it never extracts the data unless I add the splat operator.
Here is the code in question
# in a service file, let's call it service.rb
def self.format_user_home_address_data(user)
# This doesn't work in the console but sometimes works when run in my Rails project
home_address_data = user.attributes.extract!(User::HOME_ADDRESS_FIELDS)
home_address_data[:address_type] = "home"
home_address_data
end
# at the end this method will sometimes return { address_type: "home" } or
# sometimes it'll actually return the extracted attributes as expected
HOME_ADDRESS_FIELDS is just an array with the values ["address_line_1", "city", "state", "zip"]
Anyway I know that to get it to run correctly I need to do this
home_address_data = user.attributes.extract!(*User::HOME_ADDRESS_FIELDS)
But does anyone know why I was able to get away without adding the splat operator for so long? Is there some Ruby on Rails magic that is only sometimes happening? What's the deal?
Well, let's check it out. There is no any magic behind attributes.extract! in the end. Here is an actual implementation of this method from Rails source code:
def extract!(*keys)
keys.each_with_object(self.class.new) { |key, result|
result[key] = delete(key) if has_key?(key)
}
end
Link: click. As you can see, it creates new hash, goes over the keys one by one and moves value from self to this new array. So, if you give an Array argument to this method then key in the block will be an Array as well. So, it won't be found. So, no way it may work for array argument. The only one possibility is that something else is passed instead of User::HOME_ADDRESS_FIELDS.
My code in ServiceDetailController
$users = $this->ServiceDetail->Users->find()->extract('first_name')->where(['position' => 2]);
I get an error:
Call to undefined method Cake\ORM\ResultSet::where()
Debugging basics: Check if the method exists in the called object. If not ask yourself why. Then check what extract() returns and you'll get your answer. You basic problem, as a metaphor is that you try to drink from a bottle before opening it. You can't extract without having a result first.
Extract does not return a query object. First build your query, then execute it, all() for example, and then call extract on the result object because it implements a collection that allows you to call extract() on it.
On my application i have to search for an alphanumeric id which return one or more rows of data. On each of these rows a link is present i have to click on the first link.
Unfortunately it doesn't have any unique properties so i cannot add it to the OR. Instead i used descriptive programming something like below
'returns false
page.Link("class:=ng-binding","innertext:=AplhaID","html tag:=A").Exist
QTP fails to identify the object with the above code. So Instead of this i tried using Description object something like the below code
Set oDesc = Description.Object
oDesc("class").Value = "ng-binding"
oDesc("html tag").Value = "A"
oDesc("innertext").Value = "AplhaID"
Set lnk = page.ChildObjects(oDesc)
'gives me 2 which is correct. There are two links
msgbox lnk.Count
'highlights the correct link
lnk(0).Highlight
I do not know what could be causing this behavior. I thought is could be because multiple links match the description but I perform this search for multiple ids and eventhough multiple rows are returned the descriptive programming code is able to identify the correct row and proceed.
I looked at QTP descriptive programming issue but my link's property values do not have special characters.
In order to use Descriptive string method, ensure that you have only one object matching the given properties.
Below statement might fail if there are more than 1 object with the given properties.
page.Link("class:=ng-binding","innertext:=AplhaID","html tag:=A").Exist
So , you need to make the statement to find an object uniquely. Try this. It will work!
page.Link("class:=ng-binding","innertext:=AplhaID","html tag:=A", "index:=0").Exist
I keep coming across this issue where I am trying to update a record using the update() method.
It always works when I query an object using filter.
my_dictionary = {"key":"Val","another":"Val"}
thing = Thing.objects.filter(pk=1)
thing[0].update(**my_dictionary) wrote it wrong in the original question.
thing.update(**my_dictionary)
When I query the object using get() it keeps telling me that the object has no method update()
my_dictionary = {"key":"Val","another":"Val"}
thing = Thing.objects.get(pk=1)
thing.update(**my_dictionary)
Isn't a model object the same in both cases? Why would one have an update method and the other one not? Any insight would be greatly appreciated.
The documentation is very explicit about this:
filter() will always give you a QuerySet, even if only a single object matches the query - in this case, it will be a QuerySet containing a single element.
If you know there is only one object that matches your query, you can use the get() method on a Manager which returns the object directly.
Your first snippet returns a QuerySet, which has an update method. The second snippet returns a model instance, which doesn't.
Note that you have not shown the exact code you are using: thing[0].update would give exactly the same error as the second snippet.
You're using QuerySet.update() and ModelInstance.save().
If you’re just updating a record and don’t need to do anything with the model object, the most efficient approach is to call update(), rather than loading the model object into memory. For example, instead of doing this:
e = Entry.objects.get(id=10)
e.comments_on = False
e.save()
...do this:
Entry.objects.filter(id=10).update(comments_on=False)
I have a following model in the Google appengine app.
class TestModel(db.Model):
names = db.StringListProperty(required=False)
So, I want to get entries which has not empty in names property. I tried like this.
TestModel.all().filter('names !=', [])
But it raises the exception: BadValueError: Filtering on lists is not supported
How can I filter it? or Should I check one by one like following?
for entry in TestModel.all():
if len(entry.names) > 0:
result.append(entry)
Try this:
TestModel.all().filter('names >=', None)
This will give you every entity with at least one value set for names, i.e. every value in the index.