mercredi 13 août 2014

python - Django formes et valeurs initiales - Stack Overflow


I'm after a specific behavior - I want to be able to save the values any user enters when a form is run, and pre-populate the form with those values the next time it is run. I tried using the initial value to achieve this, but I'm getting results that I fail to understand, particularly when specifying either a FileField or when employing a FileInput widget.


See the various scenarios below and the results that I get with each. Note that I'm establishing the form fields dynamically in the __init__() of the form, but for the sake of completeness Scenario 5 looks at the "conventional" approach of populating initial values by passing an initial value dict from the view. Because everything works as expected when using a CharField without a FileInput widget, I'm almost thinking that the initial argument doesn't work when specifying a file input field. I'm getting inconsistent behavior w/regard to the form's is_valid() method any time I use a FileField or FileInput widget.


I have read the Django documentation re form fields, initial values, bound and unbound forms, and form validation, and I still can't understand why I'm getting the results shown below.


Any help in understanding this, or suggestions of a better way to accomplish what I'm trying to do is greatly appreciated.


# Scenario 1
self.fields['file_name'] = forms.CharField(required=True, label='File to import',
initial='F:/Repository/file_name.csv')
# Result: Initial value appears on form
# Without modifying the value displayed, form.is_valid() returns True
# Removing the value displayed (blanking the field) form.is_valid() returns False

# Scenario 2
self.fields['file_name'] = forms.FileField(required=True, label='File to import',
initial='F:/Repository/file_name.csv')
# Result: Initial value does NOT appear on the form
# Without entering a value, form.is_valid() returns True

# Scenario 3
self.fields['file_name'] = forms.CharField(required=True, label='File to import',
initial='F:/Repository/file_name.csv', widget=forms.FileInput)
# Result: Initial value does NOT appear on the form
# Without entering a value, form.is_valid() returns False
# Using the FileInput widget to select a file, form.is_valid() still returns False

# Scenario 4
self.fields['file_name'] = forms.FileField(required=True, label='File to import',
initial='F:/Repository/file_name.csv', widget=forms.FileInput)
# Result: Initial value does NOT appear on the form
# Without selecting a file, form.is_valid() returns True
# Selecting a file, form.is_valid() returns True

# Scenario 5
self.fields['file_name'] = forms.FileField(required=True, label='File to import',
widget=forms.FileInput)
# initial = {'file_name': 'F:/Repository/file_name.csv'} passed as an
# argument to the form
# Without entering a value, form.is_valid() returns False
# Using the FileInput widget to select a file, form.is_valid() still returns False



If you choose a file using filefiled input, then browser, using its inner magic, shows the file, which was chosen. You cannot achieve same thing, by giving value to filefield. You CANNOT change filefield value. See this : http://www.webdeveloper.com/forum/showthread.php?184694-Can-Javascript-change-value-in-input-type-file-field.


Moreover, when you let user upload the file, the file gets uploaded to memory and later onto disk, if you do that. After doing that, the best you can do is to create dummy textfield to contain uploaded file value. But you cannot show neither the files original path (Because you cannot know it by looking at file on server side) nor the full path of the file in server (Unsecure).



I'm after a specific behavior - I want to be able to save the values any user enters when a form is run, and pre-populate the form with those values the next time it is run. I tried using the initial value to achieve this, but I'm getting results that I fail to understand, particularly when specifying either a FileField or when employing a FileInput widget.


See the various scenarios below and the results that I get with each. Note that I'm establishing the form fields dynamically in the __init__() of the form, but for the sake of completeness Scenario 5 looks at the "conventional" approach of populating initial values by passing an initial value dict from the view. Because everything works as expected when using a CharField without a FileInput widget, I'm almost thinking that the initial argument doesn't work when specifying a file input field. I'm getting inconsistent behavior w/regard to the form's is_valid() method any time I use a FileField or FileInput widget.


I have read the Django documentation re form fields, initial values, bound and unbound forms, and form validation, and I still can't understand why I'm getting the results shown below.


Any help in understanding this, or suggestions of a better way to accomplish what I'm trying to do is greatly appreciated.


# Scenario 1
self.fields['file_name'] = forms.CharField(required=True, label='File to import',
initial='F:/Repository/file_name.csv')
# Result: Initial value appears on form
# Without modifying the value displayed, form.is_valid() returns True
# Removing the value displayed (blanking the field) form.is_valid() returns False

# Scenario 2
self.fields['file_name'] = forms.FileField(required=True, label='File to import',
initial='F:/Repository/file_name.csv')
# Result: Initial value does NOT appear on the form
# Without entering a value, form.is_valid() returns True

# Scenario 3
self.fields['file_name'] = forms.CharField(required=True, label='File to import',
initial='F:/Repository/file_name.csv', widget=forms.FileInput)
# Result: Initial value does NOT appear on the form
# Without entering a value, form.is_valid() returns False
# Using the FileInput widget to select a file, form.is_valid() still returns False

# Scenario 4
self.fields['file_name'] = forms.FileField(required=True, label='File to import',
initial='F:/Repository/file_name.csv', widget=forms.FileInput)
# Result: Initial value does NOT appear on the form
# Without selecting a file, form.is_valid() returns True
# Selecting a file, form.is_valid() returns True

# Scenario 5
self.fields['file_name'] = forms.FileField(required=True, label='File to import',
widget=forms.FileInput)
# initial = {'file_name': 'F:/Repository/file_name.csv'} passed as an
# argument to the form
# Without entering a value, form.is_valid() returns False
# Using the FileInput widget to select a file, form.is_valid() still returns False


If you choose a file using filefiled input, then browser, using its inner magic, shows the file, which was chosen. You cannot achieve same thing, by giving value to filefield. You CANNOT change filefield value. See this : http://www.webdeveloper.com/forum/showthread.php?184694-Can-Javascript-change-value-in-input-type-file-field.


Moreover, when you let user upload the file, the file gets uploaded to memory and later onto disk, if you do that. After doing that, the best you can do is to create dummy textfield to contain uploaded file value. But you cannot show neither the files original path (Because you cannot know it by looking at file on server side) nor the full path of the file in server (Unsecure).


0 commentaires:

Enregistrer un commentaire