Filtering results and pagination - django-templates

I have a template that shows a filter form and below it a list of the result records. I bind the form to the request so that the filter form sets itself to the options the user submitted when the results are returned.
I also use pagination. Using the code in the pagination documentation means that when the user clicks for the next page, the form data is lost.
What is the best way of dealing with pagination and filtering in this way?
Passing the querystring to the paginiation links.
Change the pagination links to form buttons and therefore submit the filter form at the same time, but this assumes that the user hasn't messed about with the filter options.
As above but with the original data as hidden fields.
ALJ

If you don't mind tweaking your URLs a bit you can embed the filter options directly into the URL. That actually has the very nice side benefit of making search options bookmarkable. Thus when a user clicks the next/prev buttons on the pagination then all the information will be carried forward from the URL.
You may have to split your URLs for that page up a tad though. If you've used some keyword args to the view function though, you can put all the logic for that view in one function.
Quick example
in your urls.py
urlpatterns = patterns('',
(r'^some_url/to/form/$', 'myapp.myview'),
(r'^some_url/to/form/(?P<filter>[^/]+)/$', 'myapp.myview'),
)
then in your view.py
def myview(request, filter=None):
if request.method == 'POST':
# if the form is valid then redirect the user to the URL
# with the filter args embedded
elif filter is None:
form = MyForm() # init it with the blank defaults
elif filter is not None:
# Convert your filter args to a dict
data = {'my_form_field' : filter}
form = MyForm(data)
else:
# Sanity checking just in case I missed a case. Raise an exception.
# the rest of the display logic for the initialized form
There are certainly cases where using a solution like this does not apply, but without knowing more about your specific case, I can't say.
Hope this helps!

Related

Flask rewrite url

I'm doing a small project that pulls data from tmdb's API.
Right now I have a /tv view that takes an id and request the TV show associated with that id. It results in a url like example.com/tv/23521. Looking at tmdb's own site their URL structure seems to something like "id-slug-title". Regardless of what comes after the ID it still redirects you to the right page.
How is that done? It would seem that it takes in the URL, splits it at "-" and uses the first parameter as ID. I am not sure how to do that in Flask though. I was thinking of using before and after request methods, but I'm worried that will just make unnecessary API calls. In order to get the slug title, I would have to make at least one call with the ID to get the title and then slugify that title.
The route accepts both an id and a slug, where the slug is optional:
#app.route('/tv/<int:id>', defaults={'slug': None})
#app.route('/tv/<int:id>-<slug>')
def tv(id, slug):
# ...
Note that you don't have to do any splitting yourself; the route matches if there is an integer number followed by a dash and some more text, or if it is just a number.
Only the id parameter is needed to find the right page. The slug is simply checked against the 'canonical' and you are redirected if it doesn't match:
page = load_page(id)
if slug != page.slug:
return redirect(url_for('tv', id=id, slug=page.slug))
Don't recalculate the slug each time, just store that in the database. You'll have to load the page info anyway for you to be able to serve it.
You could put that behaviour in a decorator and pass in the loaded page data into the view:
#app.route('/tv/<int:id>', defaults={'slug': None})
#app.route('/tv/<int:id>-<slug>')
#tv_page
def tv(page):
# ...
with tv_page then handling the parameters:
from functools import wraps
def tv_page(view_func):
#wraps(view_func)
def wrapper(id, slug):
page = load_page(id)
if slug != page.slug:
return redirect(url_for('tv', id=id, slug=page.slug))
return view_func(page)
return wrapper

How to load an ObjectModel with submitted values in Prestashop?

I'm using an HelperForm to display my form which has multilang features.
I also created a Model with fields (some are multilang).
The problem is, once the user submit the form, how can I fill the data from the submit form into my new model ?
I tried this :
$instance = new MyModel();
$instance->validateController();
But for some kind of odd reasons, it doesn't save the language fields, only the "direct" fields.
I thought about using validateFields and validateFieldsLang, but they stop at the first encountered error ; I'd like to list all the possible errors at once.
How can I do this?
Are you using it from the front or back office?
Admin controllers have this
$this->copyFromPost($this->object, $this->table);
Thich basically calls the object's validation

yii search form via post instead of get

I have a simple search
public function search() {
$criteria=new CDbCriteria;
$criteria->with = array('agent');
$criteria->compare('full_name',$this->full_name,true);
if ($this->gender_id != "") {
$criteria->compare('gender_id',$this->gender_id);
}
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination'=>array(
'pageSize'=>30,
),
));
}
But I don't like that the search parameters appear in the address bar when you use the get method to search. I've changed my search widget to use the post method instead:
$form=$this->beginWidget('CActiveForm', array(
'action'=>Yii::app()->createUrl($this->route),
'method'=>'post',
));
But now when I hit the search button the page just refreshes instead of showing the search results, I assume I'm missing something here...
In your actionAdmin function of the controller replace $_GET by $_POST...
if(isset($_GET['Model']))
$model->attributes=$_GET['Model'];
replace $_GET in above lines by $_POST like:
if(isset($_POST['LoginLog']))
$model->attributes=$_POST['LoginLog'];
On a side note on search it is always advised to use GET instead of POST, the basic rule i use is whenever some data needs to be submitted it should be POST, whenever some data needs to be fetched it should be GET..
Update:
The main reasons I can think of i would use GET for search
1) In searches user needs the functionality to back to previous filter, which if used as get url params, is straight forward.
2) If the filter params are in url, its extremely easy to share results after certain filters..Imagine you want to share some results with a friend, would you give him instructions to filter step by step (In case of POST), or give a direct url(GET)
3) Its very easy to change params from url, imagine currently you are visiting 2nd page, but on page while displaying filters only links to next 5 pages are displayed, but you want to jump to straight 15th page results..
There will be many more advantages, I can think of these at the moment..

Rails Select Box form helper for multiple booleans

Is there a way to use a select box in a rails form for multiple booleans? Let's say I have three weather conditions: Clear, Cloudy, Rainy that are each boolean. Can I put them in one select box titled "Weather", and when one of them is picked that one becomes 'true'?
To me, I see this as two different actions.
1) The user making a selection from a selection_box helper on the form. That variable gets set to the resource :current_weather and stored in the database.
2) After submit button is clicked then is more logic processed in the controller or through a class method. Let's say it was in the 'update' portion of CRUD in a weather tracker.
def update
#tracker = Tracker.find(params[:id])
if #tracker.current_weather == "Clear"
#do this
end
end
Maybe this will give you some ideas. Good luck!

How implement the Back Link to the page from which comes from

I have an application with associations and will pagination the pages.
The index page from the main object "cat_list" shows links to the association "data_lists". The index page has also pagination with "will_paginate"
I show for example page=3 "/cat_lists?page=3"
I click the link of a "data_lists" for example "/cat_lists/8984/data_lists"
This index page shows a list of data_lists with Edit, Destroy and a New link.
And a Back Link to the cat_lists index page now "/cat_lists"
What is the best practice to implement the features, that the Back Link now the page from which comes from?
I usually record the history in the session and then call it via redirect_to back (no colon)
def index
... do your stuff ...
record_history
end
protected
def record_history
session[:history] ||= []
session[:history].push request.url
session[:history] = session[:history].last(10) # limit the size to 10
end
def back
session[:history].pop
end
Note that this only works for GET requests.
If I understand you correctly link_to('Back', :back) is what you want.
I also use mosch's approach.
link_to('Back', :back) only uses the browsers 'back' functionality. Managing the history server side gives you more control (i.e. if you've come from a google search, guess what happens on :back).
Managing the history server side gives you the possibility to hide links that would take the user off your page. Further you can offer the user to browse multiple steps back - i.e. via dropdown.