问题
The use case I am try to address is a requirement for a user to have downloaded a file before being permitted to proceed to the next stage in a form process.
In order to achieve this, I have a Django Form to capture the user's general information which POSTS to Django view 'A'. The Form is displayed using a template which also includes an iFrame with a simple embedded button which links to the URL of Django view 'B'.
View 'B' simply sets a session variable to indicate that the download has occurred, and returns the URL of the file for download, thereby triggering the download.
As part of the validation of Form 'A' (the main Form), I need to check whether the session variable indicating file download is set.
My question is, is this best done using Form 'A' validation process, and if so, how is this best achieved?
If this is not a good approach, where should validation of this event take place?
回答1:
You could override the __init__
method for your form so that it takes request
as an argument.
class MyForm(forms.Form):
def __init__(self, request, *args, **kwargs)
self.request = request
super(MyForm, self).__init__(*args, **kwargs)
def clean(self):
if not self.request.session.get('file_downloaded', False):
raise ValidationError('File not downloaded!')
def my_view(request):
form = MyForm(request, data=request.POST)
This keeps all the validation logic in the form.
回答2:
Why not, it looks OK to me. The most convenient way of accessing request inside Form, that I know, is embedding it (i.e. Form) inside a function:
def formX(request):
class FormX(forms.Form):
def clean(self):
if not request.session.get('file_downloaded', False):
raise ValidationError('File not downloaded!')
return FormX
(Note that regarding clean(), this is pseudocode - I was writing out of my head and I probably don't remember details of form cleaning)
Then in view you just write:
def my_view(request):
form = formX(request)(...)
来源:https://stackoverflow.com/questions/3778148/django-form-validation-including-the-use-of-session-data