filter() method in python django - python

out_links = Link.objects.filter(iweb=iweb_id).order_by('-pub_date')
for link in out_links:
comments = LinkComment.objects.filter(link=link.id)
Filter method creates the list of object, so out_links is a list, right ?
Next, after for loop, I filtering again to find objects in LinkComments class by link id.
The question arises though, shoud I refer to link as it would be the object or rather a list?
I'm not shure about it as long it is django views? link.id or link['id']? My python says [ ], but django does not work.

The out_links is a queryset and in the for loop you can reach all LinkComments by:
for link in out_links:
comments = link.linkcomment_set.all()

Filter creates a QuerySet, as explained in the documentation: https://docs.djangoproject.com/en/dev/ref/models/querysets/#methods-that-return-new-querysets
If you subscript a QuerySet, like comments[n], you get the nth member (just as you would with a list). Where you have an order_by, that is in the order specified by that clause. You cannot query by id using the subscript notation.
When you iterate over the QuerySet, you get the members of the queryset, which are python model objects, and you may treat them just as you do anywhere else in your code.

Filter method creates the list of object, so out_links is a list,
right ?
Wrong. It creates QuerySet object, which also happens to be an iterable.

Related

Convert Django Queryset to list or dict

From my views.py I doing this query:
var_query = DB.objects.filter(Q(user_id=str(request.user.id)) & Q(router_name='router1' )).values('router_type', 'router_ip')
Working because I get this result:
{'router1': set(['[{"router_type": "CISCO", "router_ip": "192.168.1.1"}]'])}
the type of var_query is: <class 'django.db.models.query.QuerySet'>
When I convert this with list()
converted = list(var_query)
and this error:
AttributeError: 'set' object has no attribute 'iteritems'
becasue when a convert this queryset to list is inserted this: set(['
How to convert to real list or dict so I can work with my key or value?
It's not really clear what your final aim is. But it seems like you are overcomplicating things unnecessarily. I would suggest simplifying your approach and just filter the queryset normally (note, it looks like these Q objects are also unnecessary here, you can just pass the args in directly).
var_query = DB.objects.filter(
Q(user_id=str(request.user.id)) & Q(router_name='router1')
)
The result will be a queryset object that implements the iterator protocol and can be iterated over normally like a list or list-like object. Then to work with the fields in the data that you seem to be interested in, you can just do something like:
var_query = DB.objects.filter(
Q(user_id=str(request.user.id)) & Q(router_name='router1')
)
for obj in var_query:
router_type = obj.router_type
router_ip = obj.router_ip
# ... do other stuff with your data.
You don't need to bother using values unless you really have a proper use case for it.
If you can supply more context we can refine a more accurate solution.

How to get filter key and result tuple in Django

Assume there is a list contains all keys to search called taglist. To filter all Post contains tag in taglist, I use the following command.
Post.objects.filter(tags__tag__in=taglist).order_by('-id')
and in class Post
tags = models.ManyToManyField('PostMention')
in PostMenthion
class PostMention(models.Model):
tag = models.CharField(unique=True,max_length=200)
and I will get a Query list about the result.
Can I get a list of tuple like(each_result,tag_that_used_to_found_the_result)?
Yes, we can .annotate(..) each row with the related Tag:
from django.db.models import F
Post.objects.filter(
tags__tag__in=taglist
).annotate(
the_tag=F('tags__tag')
).order_by('-id')
Here the Post objects will have an extra attribute .the_tag, that contains the string of the tag that matched. In case multiple tags matched, multiple Post objects will be in the queryset, each with their .the_tag attribute.
We can post-process this to a 2-tuple, but I think an attribute is a better choice, since then it is clear what this field contains.

Django interpreting dict values ambiguously [duplicate]

In a Django view you can access the request.GET['variablename'], so in your view you can do something like this:
myvar = request.GET['myvar']
The actual request.GET['myvar'] object type is:
<class 'django.http.QueryDict'>
Now, if you want to pass multiple variables with the same parameter name, i.e:
http://example.com/blah/?myvar=123&myvar=567
You would like a python list returned for the parameter myvar, then do something like this:
for var in request.GET['myvar']:
print(var)
However, when you try that you only get the last value passed in the url i.e in the example above you will get 567, and the result in the shell will be:
5
6
7
However, when you do a print of request.GET it seems like it has a list i.e:
<QueryDict: {u'myvar': [u'123', u'567']}>
Ok Update:
It's designed to return the last value, my use case is i need a list.
from django docs:
QueryDict.getitem(key)
Returns
the value for the given key. If the
key has more than one value,
getitem() returns the last value. Raises
django.utils.datastructures.MultiValueDictKeyError
if the key does not exist. (This is a
subclass of Python's standard
KeyError, so you can stick to catching
KeyError
QueryDict.getlist(key) Returns the
data with the requested key, as a
Python list. Returns an empty list if
the key doesn't exist. It's guaranteed
to return a list of some sort.
Update:
If anyone knows why django dev's have done this please let me know, seems counter-intuitive to show a list and it does not behave like one. Not very pythonic!
You want the getlist() function of the GET object:
request.GET.getlist('myvar')
Another solution is creating a copy of the request object... Normally, you can not iterate through a request.GET or request.POST object, but you can do such operations on the copy:
res_set = request.GET.copy()
for item in res_set['myvar']:
item
...
When creating a query string from a QueryDict object that contains multiple values for the same parameter (such as a set of checkboxes) use the urlencode() method:
For example, I needed to obtain the incoming query request, remove a parameter and return the updated query string to the resulting page.
# Obtain a mutable copy of the original string
original_query = request.GET.copy()
# remove an undesired parameter
if 'page' in original_query:
del original_query['page']
Now if the original query has multiple values for the same parameter like this:
{...'track_id': ['1', '2'],...} you will lose the first element in the query string when using code like:
new_query = urllib.parse.urlencode(original_query)
results in...
...&track_id=2&...
However, one can use the urlencode method of the QueryDict class in order to properly include multiple values:
new_query = original_query.urlencode()
which produces...
...&track_id=1&track_id=2&...

OpenERP - NotImplementedError on evaluating result of object.browse(...)

I'm browsing for records, then I would like to perform specific code if browsing return results.
Here is my code :
sub = self.pool.get('subscription.subscription').search(cr,uid,[('partner_id','=',partner.id),('active','=',True)])
if sub:
mtp.send_mail(cr, uid, level.email_template_id.id, partner.id, context=ctx)
But it does not work, when evaluating the if condition, an exception is raised :
NotImplementedError: Iteration is not allowed on browse_record(res.partner, 15918)
I don't understand, because i'm not iterating over the result by checking if a result exist, neither calling the __iter__ method.
Thank you for your help
Cheers
In general cases the problem is that you are invoking browse method with only one ID, not a list of IDs, so the return value is only one record, not a list of records, so is not iterable.
ids can be wither a list of ids or a numeric id.
In the latter case, browse returns a single record, non iterable, instead of an iterable collection of records.
The solution is to make sure ids is a list.
Add this after method definition.
if not isinstance(ids, list):
ids = [ids]

Python - reading checkboxes

I have a few checkboxes with common name and individual variables (ID).
How can I in python read them as list?
Now I'm using
checkbox= request.POST["common_name"]
It isn't work properly, checkbox variable store only the last checked box instead of any list or something.
If you were using WebOB, request.POST.getall('common_name') would give you a list of all the POST variables with the name 'common_name'. See the WebOB docs for more.
But you aren't - you're using Django. See the QueryDict docs for several ways to do this - request.POST.getlist('common_name') is one way to do it.
checkbox = request.POST.getlist("common_name")
And if you want to select objects (say Contact objects) based upon the getlist list, you can do this:
selected_ids = request.POST.getlist('_selected_for_action')
object_list = Contact.objects.filter(pk__in=selected_ids)

Categories

Resources