Created
February 6, 2013 15:54
-
-
Save pipermerriam/4723485 to your computer and use it in GitHub Desktop.
Various django objects and helpers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ClearableFileInput(widgets.ClearableFileInput): | |
""" | |
Changes the default file widget to be easier to target with CSS | |
""" | |
template_with_initial = u'<div class="fileField"><span class="currently">%(initial_text)s:</span> %(initial)s %(clear_template)s<span class="change">%(input_text)s:</span> %(input)s</div>' | |
template_with_clear = u'<div class="clear">%(clear)s <label for="%(clear_checkbox_id)s">%(clear_checkbox_label)s</label></div>' | |
initial_template = u'<a href="{{url}}">{{name}}</a>' | |
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, | |
} | |
template = u'%(input)s' | |
substitutions['input'] = widgets.FileInput.render(self, name, value, attrs) | |
if value and hasattr(value, "url"): | |
template = self.template_with_initial | |
substitutions['initial'] = Template(self.initial_template).render(Context({ | |
'url': escape(value.url), | |
'name': escape(force_unicode(value)), | |
'value': 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'] = widgets.CheckboxInput().render(checkbox_name, False, attrs={'id': checkbox_id}) | |
substitutions['clear_template'] = self.template_with_clear % substitutions | |
return mark_safe(template % substitutions) | |
class ImageInput(ClearableFileInput): | |
template_with_initial = u'<div class="fileField">%(initial)s %(clear_template)s<span class="change">%(input_text)s:</span> %(input)s</div>' | |
initial_template = u'{% load thumbnail %}{% thumbnail value.path "100x100" as img %}<img src="{% media img.name %}">{% endthumbnail %}' | |
clear_checkbox_label = 'Delete Image' | |
class CSSClassMixin(object): | |
error_css_class = 'error' | |
required_css_class = 'required' | |
class NonBraindamagedErrorMixin(object): | |
def field_error(self, name, error): | |
self._errors = self._errors or ErrorDict() | |
self._errors.setdefault(name, ErrorList()) | |
self._errors[name].append(error) | |
class SortedIterableDict(SortedDict): | |
""" | |
Used as a template object that allows for dictionary style lookups, yet | |
iterates over the values. | |
""" | |
def __iter__(self): | |
for key in super(SortedIterableDict, self).__iter__(): | |
yield self[key] | |
class FieldsetMixin(NonBraindamagedErrorMixin): | |
FIELDSETS = tuple() | |
def get_fieldsets(self): | |
return self.FIELDSETS | |
def fieldset_error(self, name, error): | |
fieldset = self.fieldsets[name] | |
fieldset.errors = getattr(fieldset, 'errors', ErrorList()) | |
fieldset.errors.append(error) | |
self.field_error(name, error) | |
@cached_property | |
def fieldsets(self): | |
fieldsets = SortedIterableDict() | |
for fieldset_name, fieldset in self.get_fieldsets(): | |
fieldsets[fieldset_name] = SortedDict({ | |
'name': fieldset_name, | |
'fields': SortedIterableDict([(field, self[field]) for field in fieldset.get('fields', [])]), | |
'css_classes': ' '.join(fieldset.get('css_classes', [])), | |
'template_name': fieldset.get('template_name'), | |
}.items()) | |
return fieldsets | |
class BaseForm(FieldsetMixin, CSSClassMixin, forms.Form): | |
pass | |
class BaseModelForm(FieldsetMixin, CSSClassMixin, forms.ModelForm): | |
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class USPhoneNumberFieldExtension(forms.CharField): | |
regex = re.compile(r""" | |
^(?P<phone> | |
(\d+[ .-]?)? # country code | |
\(?\d{3}\)?[ .-]? # area code | |
\d{3}[ .-]? # first 3 | |
\d{4}[ .-]? # first 4 | |
) | |
# extension | |
(\s*(e|x|ext|ex|extension|xt)\.?\s*(?P<ext>\S+))? | |
$""", re.X) | |
def clean(self, value): | |
super(USPhoneNumberFieldExtension, self).clean(value) | |
if value in EMPTY_VALUES: | |
return '' | |
matches = self.regex.match(value) | |
if not matches: | |
raise forms.ValidationError('Phone numbers must be in [X-]XXX-XXX-XXXX[ex. XXX] format') | |
phone = strip_nondigits(matches.group('phone')) | |
ext = strip_nondigits(matches.group('ext') or '') | |
groups = re.match('(\d*)(\d{3})(\d{3})(\d{4})$', phone).groups() | |
groups = filter(bool, groups) | |
phone = '-'.join(groups) | |
if ext: | |
phone += ' ex. ' + ext | |
return phone |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment