Django pass CommaSeparated values to GET paramater - django

We know that django has CommaSeperated model field. But how can we pass commaSeparated string to Django GET parameter.
Whenever i try to pass something like below as GET parameter:
1,2,3,4
I receive using below code in django view
request.GET.get('productids','')
It ends up like below in django view.
'1,2,3,4'
Its ends up adding quotes around the array.
Please any Django experts help me with this issue.

You can use getlist
param_list = request.GET.getlist('productids')
If you're passing it as a single parameter then you can construct it
param_list = [int(x) for x in request.GET.get('productids', '').split(',')]

Django converts GET and POST params to string (or unicode). That means, if you're sending a list (array) as a GET param, you'll end up getting a string at the backend.
However, you can convert the string back to array. Maybe like this:
product_ids = request.GET.get('productids', '')
ids_array = list(product_ids.replace(',', '')) # remove comma, and make list
The ids_array would look like this - ['1', '2', '3'].
Update:
One thing worth noting is the ids in ids_array are strings, not integers (thanks to Alasdair who pointed this out in the comments below). If you need integers, see the answer by Sayse.

Related

Passing multiple values in a django url with dashes

I am passing several values to a view through my url. Through some blind luck (read experienced debugging (: ) I fixed an issue I had where the view was interpreting the arguments in an unexpected fashion. The old url looked like:
url(r'^explore/(?P<id>[\w\-]+)-(?P<region>[\w\-]+)-(?P<location_name>[-\w]+)-(?P<page>[\w\-]+)/$',
'project.apps.web_feed.views.display_feed', name='display_feed'),
My display_feed view looked like this:
def display_feed(request, id, region, location_name, page):
url_scheme = id + '-' + region + '-' + location_name
print location_name
There are several instances where the value for location_name was two words and the url that was called would look like this:
/explore/90-LA-Los-Angeles-0/
In my display_feed view, the value of location_name would be:
Angeles
This caused obvious problems when trying to query data and display it on the page.
When I rearranged the order of the url to have location_name as the first value like so:
url(r'^explore/(?P<location_name>[-\w]+)-(?P<id>[\w\-]+)-(?P<region>[\w\-]+)-(?P<page>[\w\-]+)/$',
'heylets.apps.web_feed.views.display_search_feed', name='search_feed'),
and updated the view to correspond with the above changes, the logic works swimmingly and the data displays on the page as expected.
I assume there are issues with the structure of the url, but I don't want to chalk this up to inexperience and move on without first understanding what I was doing wrong.
I think the issue is you were putting a ton of info in the same place without a clear delimiter. You were separating your values with a "-", but in the case of a multi-word name you were using "-" as a separator too, which can lead to unexpected results. If you are going to keep the same structure, separate your multi-word names with "_" or something different.
There may be better approaches, like the one points out: querystring.
You can get them on a dict and use them later, and you won't have that issue.
Another approach could be to separate your args with a different char, so your urls look like "/explore/90/LA/Los-Angeles/0/". This is the way it is shown in django tutorials and way cleaner than your approach.

Django Form Field for a list of strings

I need a Django Form Field which will take a list of strings.
I'll iterate over this list and create a new model object for each string.
I can't do a Model Multiple Choice Field, because the model objects aren't created until after form submission, and I can't do a Multiple Choice Field, because I need to accept arbitrary strings, not just a series of pre-defined options.
Anyone know how to do this?
Just use a regular text field delimited by commas. After you handle the form submission in the view do a comma string split based on that field. Then iterate over each one creating and saving a new model. Shouldn't be too hard.
In my case to process list of strings I used forms.JSONField(decoder="array") in my forms.py in form class
I came up with a solution -- a little hacky but it works for now.
After grabbing the form data, I stash the list in a variable:
event_locations = form_data.get('event_locations', None)
Then I remove it from form_data, so the Django Form never gets the list:
if event_locations:
del form_data['event_locations']
I instantiate my form with form_data, and handle the list separately:
f = NewEventForm(form_data)
...
for loc in event_locations:
#create new models here
I realize this doesn't directly solve the question I asked, because we still don't have a Django Form Field taking a list, but it's a way to pass in a list to a view that takes a form and be able to handle it.

use request.POST without knowing the name and number of inputs

Is there a way that become aware of name and value of inputs in request.POST?
I know i can access the value of inputs by knowing name of them like this:
name = request.POST['inputName']
but if i don't know how many inputs and with what names they are, what can i do? is there a way to loop through request.POST?
(i create my html with xsl, and because i'm creating html by parsing xml file, the number and nmame of inputs are variable. so i have to use this way)
really thanks for your help :)
The default iterator of Python dictionaries returns keys - what this means is that when you loop through a dictionary, it will return each key. Since request.POST is a "dict like" object, it works:
for i in request.POST:
print 'I have been passed the following keys: ',i
You can also do:
print 'The total number of keys in my POST request: ', len(request.POST.keys())
Try to just foreach them.
Example:
foreach(request.POST as item){
print item;
}

Variable number of fields in Django URL

I'd like a URL of the form:
... field1/eq/value1/field2/gt/value2/ ...
Where I want to filter the contents of the page in the view function based on an arbitrary number of fields (the names of which are not known in advance).
I've tried:
(r'^((?P<field>\w+)/(?P<op>[a-z]+)/(?P<value>\w+)/)*$', my_view)
But the keyword arguments are filled with the last set of three field/op/value to occur in the URL.
Is there any way that I could populate a list or dictionary based on a variable number of URl fields like this?
Or should I be doing this some completely different way?
Don't do this.
Use the query string. ?field,eq,value&field,gt,value will work out much better.

Using a string as the argument to a Django filter query

I'm trying to do a django query, but with the possibility of several different WHERE parameters. So I was thinking of doing something like:
querystring = "subcat__id__in=[1,3,5]"
Listing.objects.filter(querystring)
Here Listing is defined in my model, and it contains the Many-To-Many field subcat. However, that raises a ValueError because filter doesn't accept a string as its argument. Is there a way in Python to have a string evaluated as just its contents rather than as a string? Something like a print statement that prints the value of the string inline rather than to the standard output.
By the way, the reason I don't just do
querystring = [1,3,5]
Listing.objects.filter(subcat__id__in=querystring)
is that I'm not always filtering for subcat__id, sometimes it's one or several other parameters, and I'd rather not have to write out a bunch of separate queries controlled by if statements. Any advice is much appreciated.
Perhaps...
filter_dict = {'subcat__id__in': [1,3,5]}
Listing.objects.filter(**filter_dict)
Listing.objects.filter(**{"subcat__id__in": ast.literal_eval("[1,3,5]")})