Saving Formset in a Session - Django - django

Is here any way to store formset to a session ?
My Scenario is like this . I have a form to fill user data and upload user certificates, and in the next page(form by clicking next) there is a form to enter Professional details .
Is it possible to limit Maximum number of forms generated using a formset?

If I understand your question correctly - how to save a state of the from in a session, then starting with Django 1.4, it actually comes with a way on how to do that out of the box.
https://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/
It allows you to split a form into multiple section, which then user can fill separately. Once user fills any one section, he/she go to the next page, at which point the state of the form will be saved in a session. Once all the pages are filled, then everything can be saved to a database.
In addition, while going from one page to the other, you add logic of what should be on the next page.
Image that you have a wizard where on the first page it asks what type of content user wants to upload. Then upon going to the second page, then depending on the answer from the first page, appropriate upload fields can be present - field for video, music, or graphics.

I would have answered FormWizard but if you don't want to use it, you can simply create two forms. when the user submit the first one, you pickle it into a session and then you generate the second form. When he clicks on back link, you unPickle saved data and you prefill the form.
def submitFirstForm(request):
data = request.POST['data']
import cPickle
request.session['data'] = cPickle.dumps(data)
...
def backBtn(request):
import cPickle
data = cPickle.loads(request.session['page'])
form = DataForm(data)
...

Related

Django: Redirect to the referring page (not the current form) when an UpdateView fails validation and is then Canceled?

My Django application allows a user to navigate to an Update Form (UpdateView) from multiple locations in the application. Currently, if the form is saved successfully I can redirect without a problem to the referring page by saving request.META.HTTP_REFERER in a hidden field in the template and retrieving it in form_valid. I can leverage the HTTP_REFERER data in MOST, but not ALL cases. One of those is the following scenario:
My user navigates to the FORM A from Page X (HTTP_REFERER is set to Page X)
FORM A is submitted and does not pass validation (HTTP_REFERER is now set to FORM A instead of Page X because indeed it has self-refered.)
My user clicks Cancel (they are redirected back to FORM A instead of Page X)
Is there a way to capture the Cancel event before it is processed and perform some logic so my user gets referred back to Page X instead of being stuck in the form?

How to render order completed page in ecommerce app in django

I am currently building an ecommerce style app. I have a view new_order that processes the POST data (order info). After that, it renders an HttpResponseRedirect to order_complete which just renders order_complete.html template.
What is the best way to pass the order number to the template. Here's what I did:
messages.success(request, 'Your order number is %s ' % order.order_id)
return HttpResponseRedirect(reverse('orders:order_complete_url'))
That works nicely, however, due to the nature of messages, it disappears on page refresh. Is this an ideal behavior or there is a better way to accomplish it? Also, how would i go about passing for instance order detail, total etc, to the template?
Django's messages framework allow us to display a one-time notification message to the user after processing a form or some other types of user input. It temporarily stores messages in one request and retrieves them for display in a subsequent request (usually the next one).
So, when you refresh the page, that message will disappear and will not be displayed again.
You can use session to store variables which you want to use in your subsequent requests also.
For example:
request.session['order_number'] = order.order_id # set in session
return HttpResponseRedirect(reverse('orders:order_complete_url'))
This will set order_number in the session. Here, you can also set other variables which you need in order_complete_url view.
Then in your order_complete_url view, you can access order_number by:
order_number = request.session['order_number'] # retrieve order number from session
You can pass this order_number to context then for displaying in the template. Now, when you refresh the page, order_number will be displayed in the template.

Hit counter for pages in Django

I want to have a page counter that displays the number of visitors who have viewed a particular page on my site. Is it possible to do this using Django?
There's a Django app for that problem called django-hitcount. It's easy to use, and reusable in any of your projects.
A "page counter" is what? A persistent piece of data which gets updated by view functions and displayed by a template.
As you are no doubt already aware, all Django things have the following parts.
Model
View Function
Template
Model
If you want to keep the page counter in the database, you need a Django model.
class PageCounter( Model ):
You need to put a row into this model. Usually a "fixture" will help do this, since it's one row and you only put it in once when doing a syncdb.
View Function
Then you need to fetch and update the page counter in your view function.
pageCounter= PageCounter.objects.all()[0]
pageCounter.count += 1
pageCounter.save()
Template
Now you need to provide the value to your templates so it can be displayed.
I know this is an old post but occasionally people might have the same question.
If you want to avoid a third party library and prevent the counter being updated at every page refresh you could do the following Mixin (building on S.Lott's answer)
class BlogPostCounterMixin(object):
def get_context_data(self, **kwargs):
context = super(BlogPostCounterMixin, self).get_context_data(**kwargs)
blog_post_slug = self.kwargs['slug']
if not blog_post_slug in self.request.session:
bp = BlogPost.objects.filter(slug=blog_post_slug).update(counter=+1)
# Insert the slug into the session as the user has seen it
self.request.session[blog_post_slug] = blog_post_slug
return context
It checks if the accessed model has been stored in the session. If it has been stored in the session, it skips incrementing, else it increments the counter and adds the slug of the model to the session preventing increments for page refreshes.
Note: This is a Mixin which you require to add into your view.

django forms overwrite data when saved

If a have a form, with the data from a user, let's say a CV, and i save the data from the form into a database, but i don't want that a CV from the same user to be stored in the database more than once(when edited form instance)
I want it to be overwritten every time it is saved by one same user.
How can i do it?
thanks a lot
Django's save() should handle this for you automatically.
To give an example, you'll usually submit a form in a way something like this:
...
form = UserCVForm(request.POST, instance=user_cv)
if form.is_valid():
form.save()
...
'instance=user_cv' tells django that you want to update an existing entry - specifically 'user_cv'. Without 'instance=user_cv', Django will insert a new entry into the database.
So in short, see if a user_cv exists already with something like user_cv = UserCV.objects.get(user=user_id). If a user_cv exists, be sure to whack an instance=user_cv in when populating the form.

Sending user to a page created based on their POST request in Django

I have a form in which the user selects a few items to display on "the following page". This selection is always unique, and we will store each set of selections made using a model, indexed by the id as is par with Django models. When the user selects her choices and POSTs using the submit button, I would like for our application to store her selections in the model, and then render a page with the id of the model so that the user can get back to the page she created at any point with a simple GET request.
For example, the user goes to /coolapp/selectprefs/, makes a few selections, and clicks submit. The user should then be taken to /coolapp/selections/42 given that when the user submitted and created the record, the record was given an id of 42.
What I don't understand is how to send the user to "the following page" as a response (e.g., /coolapp/selections/42 in the above example) after she clicks the submit button. Taking a user to a page of a unique ID based on what she entered seems like a common task (e.g., it will happen when I click the button to submit this question on SO), but I'm not sure how to go about doing it, and would appreciate your advice.
Return a HttpResponseRedirect from your view that handles the POST.