- Author:
- bryanhelmig
- Posted:
- August 21, 2011
- Language:
- Python
- Version:
- 1.3
- Score:
- 2 (after 2 ratings)
Rather simple usage, modelforms/in the admin:
class CustomAdminForm(forms.ModelForm):
class Meta:
model = Something
widgets = {
'image': URLFileInput(default_exts=[".png", ".gif", ".jpg"]),
}
class SomethingAdmin(admin.ModelAdmin):
form = CustomAdminForm
admin.site.register(Something, SomethingAdmin)
Basically, this will pull the image from the URL instead of only pulling it from your harddrive for upload.
Also accepts optional default_exts argument which limits the file types. Defaults to images.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | import os, urllib, urllib2, mimetypes
from urlparse import urlparse
from django.forms.widgets import FileInput, CheckboxInput, TextInput
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
from django.core.files import File
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.files.temp import NamedTemporaryFile
from django.utils.html import escape, conditional_escape
from django.utils.translation import ugettext, ugettext_lazy
from django.utils.encoding import StrAndUnicode, force_unicode
from django.utils.safestring import mark_safe
FILE_INPUT_CONTRADICTION = object()
class URLFileInput(FileInput):
initial_text = ugettext_lazy('Currently')
input_text = ugettext_lazy('Change')
clear_checkbox_label = ugettext_lazy('Clear')
url_text_label = ugettext_lazy('From URL')
template_with_initial = u'<p class="file-upload">%(initial_text)s: %(initial)s %(clear_template)s<br />%(url_template)s<br />%(input_text)s: %(input)s</p>'
template_only_url = u'<p class="file-upload">%(url_template)s<br />%(input_text)s: %(input)s</p>'
template_with_clear = u'<span class="clearable-file-input">%(clear)s <label for="%(clear_checkbox_id)s">%(clear_checkbox_label)s</label></span>'
template_with_url = u'%(url_text_label)s: %(url)s'
def clear_checkbox_name(self, name):
"""
Given the name of the file input, return the name of the clear checkbox
input.
"""
return name + '-clear'
def clear_checkbox_id(self, name):
"""
Given the name of the clear checkbox input, return the HTML id for it.
"""
return name + '_id'
def url_text_name(self, name):
"""
Given the name of the file input, return the name of the url text
input.
"""
return name + '-url-clear'
def url_text_id(self, name):
"""
Given the name of the url text input, return the HTML id for it.
"""
return name + '_url_id'
def render(self, name, value, attrs=None):
substitutions = {
'initial_text': self.initial_text,
'input_text': self.input_text,
'clear_template': '',
'clear_checkbox_label': self.clear_checkbox_label,
'url_text_label': self.url_text_label,
}
template = self.template_only_url
substitutions['input'] = super(URLFileInput, self).render(name, value, attrs)
if value and hasattr(value, "url"):
template = self.template_with_initial
substitutions['initial'] = (u'<a href="%s">%s</a>'
% (escape(value.url),
escape(force_unicode(value))))
if not self.is_required:
checkbox_name = self.clear_checkbox_name(name)
checkbox_id = self.clear_checkbox_id(checkbox_name)
substitutions['clear_checkbox_name'] = conditional_escape(checkbox_name)
substitutions['clear_checkbox_id'] = conditional_escape(checkbox_id)
substitutions['clear'] = CheckboxInput().render(checkbox_name, False, attrs={'id': checkbox_id})
substitutions['clear_template'] = self.template_with_clear % substitutions
text_name = self.url_text_name(name)
text_id = self.url_text_id(text_name)
substitutions['url_text_name'] = conditional_escape(text_name)
substitutions['url_text_id'] = conditional_escape(text_id)
substitutions['url'] = TextInput().render(text_name, "", attrs={'id': text_id, "style":"width:400px"})
substitutions['url_template'] = self.template_with_url % substitutions
return mark_safe(template % substitutions)
def value_from_datadict(self, data, files, name):
upload = super(URLFileInput, self).value_from_datadict(data, files, name)
if not self.is_required and CheckboxInput().value_from_datadict(
data, files, self.clear_checkbox_name(name)):
if upload:
# If the user contradicts themselves (uploads a new file AND
# checks the "clear" checkbox), we return a unique marker
# object that FileField will turn into a ValidationError.
return FILE_INPUT_CONTRADICTION
# False signals to clear any existing value, as opposed to just None
return False
url = TextInput().value_from_datadict(data, files,
self.url_text_name(name))
if url:
validate = URLValidator(verify_exists=False)
try:
validate(url)
except ValidationError, e:
url = None
parsed_url = urlparse(url)
name = os.path.basename(parsed_url[2])
ext = os.path.splitext(parsed_url[2])[1]
if url and ext in [".png", ".gif", ".jpg"]:
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
ze_file = opener.open(url).read()
upload = SimpleUploadedFile(name=name, content=ze_file, content_type=mimetypes.guess_type(name))
return upload
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 8 months ago
Comments
Thanks. This is really useful, however the description mentions a
default_exts
argument which does not appear to be used anywhere. Conversely, the extensions accepted are hardcoded:#
Please login first before commenting.