Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Respect My Net
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Thomas Lohninger
Respect My Net
Commits
868f805e
Commit
868f805e
authored
Mar 08, 2016
by
Okhin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixing the multifile upload part
parent
0332e33d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
45 additions
and
113 deletions
+45
-113
bt/multifile.py
bt/multifile.py
+45
-104
bt/views.py
bt/views.py
+0
-9
No files found.
bt/multifile.py
View file @
868f805e
...
...
@@ -6,30 +6,23 @@ Released into the Public Domain
"""
from
django.utils.encoding
import
force_unicode
from
django.utils.datastructures
import
MultiValueDict
from
django.utils.datastructures
import
MultiValueDict
,
MergeDict
from
django.utils.translation
import
ugettext
from
django.forms.fields
import
Field
,
EMPTY_VALUES
from
django.core.files.uploadedfile
import
UploadedFile
from
django.forms.widgets
import
FileInput
from
django.forms.widgets
import
Input
,
FILE_INPUT_CONTRADICTION
from
django.forms.util
import
ErrorList
,
ValidationError
,
flatatt
from
django.utils.safestring
import
mark_safe
class
MultiFileInput
(
FileInput
):
FILE_INPUT_EMPTY_VALUE
=
object
()
class
MultiFileInput
(
Input
):
"""
A widget to be used by the MultiFileField to allow the user to upload
multiple files at one time.
"""
def
__init__
(
self
,
attrs
=
None
,
*
args
,
**
kwargs
):
"""
Create a MultiFileInput.
The 'count' attribute can be specified to default the number of
file boxes initially presented.
"""
super
(
MultiFileInput
,
self
).
__init__
(
attrs
,
*
args
,
**
kwargs
)
self
.
attrs
=
{
'count'
:
1
}
if
attrs
:
self
.
attrs
.
update
(
attrs
)
input_type
=
'file'
needs_multipart_form
=
True
def
render
(
self
,
name
,
value
,
attrs
=
None
):
"""
...
...
@@ -37,56 +30,23 @@ class MultiFileInput(FileInput):
Should not be overridden. Instead, subclasses should override the
js, link, and/or fields methods which provide content to this method.
"""
final_attrs
=
self
.
build_attrs
(
attrs
,
type
=
self
.
input_type
,
name
=
name
+
'[]'
)
count
=
final_attrs
[
'count'
]
if
count
<
1
:
count
=
1
del
final_attrs
[
'count'
]
js
=
self
.
js
(
name
,
value
,
count
,
final_attrs
)
link
=
self
.
link
(
name
,
value
,
count
,
final_attrs
)
fields
=
self
.
fields
(
name
,
value
,
count
,
final_attrs
)
return
mark_safe
(
js
+
link
+
fields
)
def
fields
(
self
,
name
,
value
,
count
,
attrs
=
None
):
"""
Renders the necessary number of file input boxes.
"""
return
u
''
.
join
([
u
'<input class="attachments"%s />
\n
'
%
flatatt
(
dict
(
attrs
,
id
=
attrs
[
'id'
]
+
str
(
i
)))
for
i
in
range
(
count
)])
if
attrs
is
None
:
attrs
=
{}
def
link
(
self
,
name
,
value
,
count
,
attrs
=
None
):
"""
Renders a link to add more file input boxes.
"""
return
u
"<div><a id='add_attach' onclick=
\"
javascript:new_%(name)s()
\"
>Add more attachments</a></div>"
%
{
'name'
:
name
}
name
+=
'[]'
attrs
[
'multiple'
]
=
'multiple'
def
js
(
self
,
name
,
value
,
count
,
attrs
=
None
):
"""
Renders a bit of Javascript to add more file input boxes.
"""
return
u
"""
<script>
<!--
%(id)s_counter=%(count)d;
function new_%(name)s() {
b=document.getElementById('%(id)s0');
c=b.cloneNode(false);
c.id='%(id)s'+(%(id)s_counter++);
b.parentNode.insertBefore(c,b);
}
-->
</script>
"""
%
{
'id'
:
attrs
[
'id'
],
'name'
:
name
,
'count'
:
count
}
return
super
(
MultiFileInput
,
self
).
render
(
name
,
None
,
attrs
=
attrs
)
def
value_from_datadict
(
self
,
data
,
files
,
name
):
"""
File widgets take data from FILES, not POST.
File widget takes data from FILES, not POST
we need to add [] for w3c recoomendation
"""
name
=
name
+
'[]'
if
isinstance
(
files
,
MultiValueDict
):
name
+=
'[]'
if
isinstance
(
files
,
(
MultiValueDict
,
MergeDict
)
):
return
files
.
getlist
(
name
)
else
:
return
None
return
files
.
get
(
name
,
None
)
def
id_for_label
(
self
,
id_
):
"""
...
...
@@ -102,56 +62,37 @@ class MultiFileField(Field):
A field allowing users to upload multiple files at once.
"""
widget
=
MultiFileInput
count
=
1
max_length
=
None
allow_empty_file
=
None
def
__init__
(
self
,
count
=
1
,
strict
=
False
,
*
args
,
**
kwargs
):
"""
strict is whether the number of files uploaded must equal count
"""
self
.
count
=
count
self
.
strict
=
strict
super
(
MultiFileField
,
self
).
__init__
(
*
args
,
**
kwargs
)
def
widget_attrs
(
self
,
widget
):
"""
Adds the count to the MultiFileInput widget.
"""
if
isinstance
(
widget
,
MultiFileInput
):
return
{
'count'
:
self
.
count
}
return
{}
def
clean
(
self
,
data
):
def
to_python
(
self
,
data
):
"""
Cleans the data and makes sure that all the files had some content.
Also checks whether a file was required.
"""
super
(
MultiFileField
,
self
).
clean
(
data
)
if
not
self
.
required
and
data
in
EMPTY_VALUES
:
if
data
in
EMPTY_VALUES
:
return
None
try
:
f
=
map
(
lambda
a
:
UploadedFile
(
a
[
'filename'
],
a
[
'content'
]),
data
)
except
TypeError
:
raise
ValidationError
(
ugettext
(
u
"No file was submitted. Check the encoding type on the form."
))
except
KeyError
:
raise
ValidationError
(
ugettext
(
u
"No file was submitted."
))
for
a_file
in
f
:
if
not
a_file
.
content
:
raise
ValidationError
(
ugettext
(
u
"The submitted file is empty."
))
if
self
.
strict
and
len
(
f
)
!=
self
.
count
:
raise
ValidationError
(
ugettext
(
u
"An incorrect number of files were uploaded."
))
return
f
class
FixedMultiFileInput
(
MultiFileInput
):
"""
A MultiFileInput widget that doesn't print the javascript code to allow
the user to add more file input boxes.
"""
def
link
(
self
,
name
,
value
,
count
,
attrs
=
None
):
return
u
''
def
js
(
self
,
name
,
value
,
count
,
attrs
=
None
):
return
u
''
if
data
is
FILE_INPUT_EMPTY_VALUE
:
raise
validationError
(
self
.
Error_messages
[
'empty_multiply'
])
# UploadedFile objects should have name and size attributes
for
d
in
data
:
try
:
file_name
=
d
.
name
file_size
=
d
.
size
except
AttributeError
:
raise
ValidationError
(
self
.
Error_messages
[
'invalid'
])
if
self
.
max_length
is
not
None
and
file_size
>
self
.
max_length
:
error_values
=
{
'max'
:
self
.
max_length
,
'length'
:
file_size
}
raise
ValidationError
(
self
.
error_messages
[
'max_length'
]
%
error_values
)
if
not
file_name
:
raise
ValidationError
(
self
.
error_messages
[
'invalid'
])
if
not
self
.
allow_empty_file
and
not
file_size
:
raise
ValidationError
(
self
.
Error_messages
[
'empty'
])
return
data
def
bound_data
(
self
,
data
,
initial
):
if
data
in
(
None
,
FILE_INPUT_EMPTY_VALUE
,
FILE_INPUT_CONTRADICTION
):
return
initial
return
data
bt/views.py
View file @
868f805e
...
...
@@ -192,15 +192,6 @@ class AddForm(FormView):
messages
.
add_message
(
self
.
request
,
messages
.
INFO
,
_
(
'Thank you for submitting this report, you will receive a verification email immediately, if not check your spam folder.'
))
return
super
(
AddForm
,
self
).
form_valid
(
form
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
# We needto do special work with the form view
form
=
self
.
form_class
(
request
.
POST
,
request
.
FILES
)
if
form
.
is_valid
():
form
.
save
()
return
redirect
(
self
.
success_url
)
else
:
return
render
(
request
,
self
.
template_name
,
{
'form'
:
form
})
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
AddForm
,
self
).
get_context_data
(
**
kwargs
)
reports
=
sorted
([(
i
[
'total'
],
i
[
'id'
])
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment