I did a simple search view to query based on this inputs.
def search(request):
try:
query_x = request.GET.get('query_x')
query_y = request.GET.get('query_y')
points_returned = request.GET.get('points_returned')
distance_condition = request.GET.get('distance_condition')
object_list = Points.objects.filter(
geom_point__distance_lte=('POINT({0} {1})'.format(query_x, query_y), D(km=10))
).order_by('geom_point')[:int(points_returned)]
request.session['query_x'] = query_x
return render_to_response('search_results.html', {'object_list': object_list})
except KeyError:
return render_to_response('home.html')
This search will be used many times (probably with same values) so I want to save and list all the inputs used to do the query by the user (for query_x and query_y variables). I already achieved to get the value in template, but just the last one input appear when I put {{request.session.query_x}} in the template to see the results - I need to get all values used.
From wherever you are calling search function you can create a session variable of list there before calling search
request.session['query_x'] = list().
instead of doing request.session['query_x'] = query_x you can simply do request.session['query_x'].append(query_x) and access all query_x using request.session['query_x']
I have a django class like this:
class my_thing(models.Model):
AVAILABLE = 1
NOT_AVAILABLE = 2
STATUSES = (
(AVAILABLE, "Available"),
(NOT_AVAILABLE, "Not available")
)
status = models.IntegerField(...., choices = STATUSES)
In another bit of code I have the number corresponding to a status, but due to some legacy code I need to compare it via strings (and I don't want to hard code it anywhere other than the model definition - DRY)
So in the code I have the number "1" and I want to get the text "Available".
My current (awful) workaround is to do the following:
status_getter = my_thing()
my_thing.status = my_thing.AVAILABLE
comparison_str = status_getter.get_status_display()
Is there a better/builtin way to directly access the string value for the field's choices given that I don't have an object of that type already instantiated? I could write a function
def get_status_on_value(self, value):
for tup in STATUSES:
if tup[0] == value:
return tup[1]
But I have a sneaking suspicion django has a built-in way to do this
Not really. Your best bet is to convert the CHOICES tuple to a dict and do a lookup:
status_dict = dict(my_thing.STATUSES)
return status_dict[value]
Is there any (efficient, or built in) way that allows me get a list of an object field when using the Objects.filter?
for example if I have a model
class Follow(models.Model):
point = Models.ForeignKey(Point)
target = Models.ForeignKey(Pages)
Can I do a query that will return
[<Point>, <Point>, <Point>]
such that those points are the ones who are following, say, target_id = 1. Or in other words, the points that occure in
Follow.objects.filter(target_id=1)
I realize that I can do the query, and then do some python code, looping trough the result to get the fields that I want, but is there a way I can do it in Django?
I am trying to prepare search form where user is able to type 1, 2 or all (3 in this case) search filters.
Lets say that search filters are:
last name, phone and address. I am trying to filter queryset by:
if filterForm.is_valid():
last_name = filterForm.cleaned_data.get('last_name')
phone= filterForm.cleaned_data.get('phone')
address = filterForm.cleaned_data.get('address')
if last_name is None and phone is None and address is None:
pass
#we dont do search id db
else:
clients = Client.objects.filter(Q(last_name__contains=last_name) | Q(phone=phone) | Q(address__contains=address))
Each search key may be blank.
Unfortunately, it returns more results then expected. When I type in search filter "Example" as last name field, it returns all fields with this last name + many others rows.
Any idea how to fix this search issue?
I believe that your search returns more results than expected when any of the search keys are blank since a blank key will match any row with a value.
By only filtering on keys that contains a value it should work better.
Here is one example of how it can be done:
if filterForm.is_valid():
last_name = filterForm.cleaned_data.get('last_name')
phone= filterForm.cleaned_data.get('phone')
address = filterForm.cleaned_data.get('address')
import operator
predicates = []
if last_name:
predicates.append(Q(last_name__contains=last_name))
if phone:
predicates.append(Q(phone=phone))
if address:
predicates.append(Q(address__contains=address))
if len(predicates) == 0:
# Nothing to search for
pass
else:
clients = Client.objects.filter(reduce(operator.or_, predicates))
The code above will dynamically add filters that shall be added to the query. The usage of oprator.or_ will concatenate the statements with OR (=at least one statement needs to be satisfied). If you instead want all statements to be satisfied you can use operator.and_ instead.
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