📜 ⬆️ ⬇️

Multiload files, version N

Since ancient times, when the Internet was young and slow, the most common browser was not IE, but Mosaic, did not go to the Internet, but called ... I was often tormented by the question - why can I choose only one file in the file dialogs? Why, if there are three file fields in the form, then each of them should be poked? Couldn't it be more convenient?
Time passed, javascript appeared, CGI, but the file fields were still selfish. Then a flash appeared, html5, the situation began to change, but ... The file field has the same essence - the file, not the file s ! Although there are many workarounds ...

So, colleagues, as you may have guessed, I want to share with you another “bicycle”. And I will be extremely happy if he makes someone's life a little easier. But before continuing, I cannot fail to thank the creators of such a wonderful tool as Plupload , a cross -browser multi-file loader.

asv_files


So, get acquainted, asv_files is a custom field for the form (hereinafter and for the model), allowing you to load N files into yourself. Not only the field, but also some piping, which allows surviving already loaded files with such events as the invalid form and sending it to repair for refilling. As well as a method that allows you to easily attach these files to any instance of any model using ContentTypes.

The creators of plupload promise cross-browser compatibility and I have no reason not to believe them. At least in IE, Opere, FireFox and Chrome, the field behaves as it should be.
')

Ideology and basic tenets


So, the basic tenets by which I was guided:

Installation


The complexity of the installation is amazing:
$ pip install asv_files 

At the same time, asv_files will bring along some dependencies, one of which ( asv_media ) contains both jQuery and plupload and is able to render them via staticfiles.

Then you will have to connect the asv_files, asv_media and django.contrib.sites applications in settings.py
 INSTALLED_APPS = ( ..... 'django.contrib.sites', ..... 'asv_media', 'asv_files', ..... ) 

Create the required models using manage.py:
 $ python manage.py syncdb 

And invite the invisible front fighters in urls.py query handler:
 from django.conf.urls import patterns, include, url urlpatterns = patterns('', ..... url('AnY_YoUr_LiKe_PaTh/', include('asv_files.urls', namespace='asv_files')), ..... 

You can connect an RPC responder at any URL, it is important to keep the above namespace unchanged.

How to use


Working with forms in Django is almost independent of whether you use classic views or switched to class-based. The essence is the same:

describe the form:
 from django import forms from asv_files.fields import CTfilesFormField class TestForm(forms.Form): #..... files = CTfilesFormField() #..... 

use it in the view:
 def TestView(request, ...): obj = Articles.objects.get(.........) if request.method == 'POST': form = TestForm(request.POST) if form.is_valid(): # ..... files = form.cleaned_data['files'] for i in files.get_files(): print('file {frn} saved as {fn} ({fp}) and have ID:{id}'.format( frn = i.get_realname(), fn = i.get_filename(), fp = i.get_filepath(), id = i.fileid, )) i.attach_to(obj) # attach to OBJ through ContentTypes #i.delete() # remove file from database and storage files.delete() # remove session and her files from database and storage else: form = TestForm() return render(request, 'template.html', { 'form': form, } 

Do not forget to connect media files correctly in the template:
 {% extends "base.html" %} {% block add_to_head %} {{form.media}} {% endblock %} {% block wp %} <hr> <form method="POST" action="{% url demo:form1 %}">{% csrf_token %} <table>{{ form.as_table }}</table> <input type="submit"> <input type="reset"> </form> {% endblock %} 

The “add_to_head” block, of course, must exist in your base template.

Management through manage.py


The manage.py has an uploads command, with which you can manage download sessions and temporary files (that is, the files that you uploaded, but the form did not upload, or upload, but the programmer forgot to erase the files in the form submission handler):
 $ ./manage.py uploads --help Usage: ./manage.py uploads [options] <sess_ID or filename> Managament for upload files and sessions Options: --sessions list unclosed upload sessions and it's files, if exist --realname display real (user's) file name near file name --no-files, --nofiles do not display information about files --older=XX use only sessions older than XX hours --only-uuids, --onlyuuids show only session's UUIDs --remove remove upload session and her files 

So, there are two main commands:
 $ ./manage.py uploads --sessions 
and
 $ ./manage.py uploads --remove sessID-1 sessID-2 ... sessID-N 

The first shows the incomplete download sessions, their files, and other related information.
The second one deletes the listed sessions and the corresponding files from the DB.

The keys to the uploads --sessions command are:


And in conclusion I want to ... say ...


Source asv_files are here .
Documentation, written, as always, in a hurry - next .
A small demo (CBV is used for diversity), illustrating the work of two fields side by side - at the opposite end of the continent .
And the amazing documentation on CBV is closer than you might think ...

I am pleased to accept criticism, bugfixes, suggestions.
Thanks for attention.

UPD: Opera is repaired, Safari loads, but adds file by html4

Supported browsers: InternetExplorer 7+, Firefox, Chrome, Opera, Safari

Source: https://habr.com/ru/post/144052/


All Articles