Styling of POST, PUT forms. Add add_class filter.

This commit is contained in:
Alec Perkins 2012-09-09 15:17:44 -04:00
parent 4500103337
commit 8c0bd39f12
4 changed files with 95 additions and 34 deletions

View File

@ -0,0 +1,13 @@
/*
This CSS file contains some tweaks specific to the included Bootstrap theme.
It's separate from `style.css` so that it can be easily overridden by replacing
a single block in the template.
*/
.form-actions {
background: transparent;
border-top-color: transparent;
}

View File

@ -51,4 +51,8 @@ h2, h3 {
#options-form {
margin-right: 1em;
}
}
.errorlist {
margin-top: 0.5em;
}

View File

@ -1,6 +1,7 @@
{% load url from future %}
{% load urlize_quoted_links %}
{% load add_query_param %}
{% load add_class %}
{% load optional_login %}
{% load static %}
<!DOCTYPE html>
@ -9,7 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
{% block bootstrap_theme %}
<link rel="stylesheet" type="text/css" href='{% get_static_prefix %}djangorestframework/css/bootstrap.min.css'/>
<link rel="stylesheet" type="text/css" href="{% get_static_prefix %}djangorestframework/css/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="{% get_static_prefix %}djangorestframework/css/bootstrap-tweaks.css"/>
{% endblock %}
<link rel="stylesheet" type="text/css" href='{% get_static_prefix %}djangorestframework/css/style.css'/>
{% block extrastyle %}{% endblock %}
@ -116,69 +118,71 @@
{{ content|urlize_quoted_links }}</pre>{% endautoescape %}
</div>
{% comment %}
{# These are disabled since the forms don't work with 2.0.0 yet #}
{% if response.status_code != 403 %}
{% if 'POST' in allowed_methods %}
<form action="{{ request.get_full_path }}" method="POST" {% if post_form.is_multipart %}enctype="multipart/form-data"{% endif %}>
<fieldset class='module aligned'>
<form action="{{ request.get_full_path }}" method="POST" {% if post_form.is_multipart %}enctype="multipart/form-data"{% endif %} class="form-horizontal">
<fieldset>
<h2>POST: {{ name }}</h2>
{% csrf_token %}
{{ post_form.non_field_errors }}
{% for field in post_form %}
<div class='form-row'>
{{ field.label_tag }}
{{ field }}
<span class='help'>{{ field.help_text }}</span>
{{ field.errors }}
</div>
<div class="control-group {% if field.errors %}error{% endif %}">
{{ field.label_tag|add_class:"control-label" }}
<div class="controls">
{{ field }}
<span class="help-inline">{{ field.help_text }}</span>
{{ field.errors|add_class:"help-block" }}
</div>
</div>
{% endfor %}
<button class="btn btn-primary" title="Do a POST request on the {{ name }} resource">POST</button>
<div class="form-actions">
<button class="btn btn-primary" title="Do a POST request on the {{ name }} resource">POST</button>
</div>
</fieldset>
</form>
</form>
{% endif %}
{% if 'PUT' in allowed_methods and api_settings.FORM_METHOD_OVERRIDE %}
<form action="{{ request.get_full_path }}" method="POST" {% if put_form.is_multipart %}enctype="multipart/form-data"{% endif %}>
<fieldset class='module aligned'>
<form action="{{ request.get_full_path }}" method="POST" {% if put_form.is_multipart %}enctype="multipart/form-data"{% endif %} class="form-horizontal">
<fieldset>
<h2>PUT: {{ name }}</h2>
<input type="hidden" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="PUT" />
{% csrf_token %}
{{ put_form.non_field_errors }}
{% for field in put_form %}
<div class='form-row'>
{{ field.label_tag }}
{{ field }}
<span class='help'>{{ field.help_text }}</span>
{{ field.errors }}
</div>
<div class="control-group {% if field.errors %}error{% endif %}">
{{ field.label_tag|add_class:"control-label" }}
<div class="controls">
{{ field }}
<span class='help-inline'>{{ field.help_text }}</span>
{{ field.errors|add_class:"help-block" }}
</div>
</div>
{% endfor %}
<button class="btn btn-primary js-tooltip" title="Do a PUT request on the {{ name }} resource">PUT</button>
<div class="form-actions">
<button class="btn btn-primary js-tooltip" title="Do a PUT request on the {{ name }} resource">PUT</button>
</div>
</fieldset>
</form>
</form>
{% endif %}
{% if 'DELETE' in allowed_methods and api_settings.FORM_METHOD_OVERRIDE %}
<form action="{{ request.get_full_path }}" method="POST">
<fieldset class='module aligned'>
<form action="{{ request.get_full_path }}" method="POST" class="form-horizontal">
<fieldset>
<h2>DELETE: {{ name }}</h2>
{% csrf_token %}
<input type="hidden" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="DELETE" />
<button class="btn btn-danger js-tooltip" title="Do a DELETE request on the {{ name }} resource">DELETE</button>
<div class="form-actions">
<button class="btn btn-danger js-tooltip" title="Do a DELETE request on the {{ name }} resource">DELETE</button>
</div>
</fieldset>
</form>
</form>
{% endif %}
{% endif %}
{% endcomment %}
</div>
<!-- END content-main -->

View File

@ -0,0 +1,40 @@
"""
From http://stackoverflow.com/questions/4124220/django-adding-css-classes-when-rendering-form-fields-in-a-template
The add_class filter allows for inserting classes into template variables that
contain HTML tags, useful for modifying forms without needing to change the
Form objects.
To use:
{{ field.label_tag|add_class:"control-label" }}
will insert the class `controls-label` into the label tag generated by a form.
In the case of Django REST Framework, the filter is used to add Bootstrap-specific
classes to the forms, while still allowing non-Bootstrap customization of the
browsable API.
"""
import re
from django.utils.safestring import mark_safe
from django import template
register = template.Library()
class_re = re.compile(r'(?<=class=["\'])(.*)(?=["\'])')
@register.filter
def add_class(value, css_class):
string = unicode(value)
match = class_re.search(string)
if match:
m = re.search(r'^%s$|^%s\s|\s%s\s|\s%s$' % (css_class, css_class,
css_class, css_class),
match.group(1))
print match.group(1)
if not m:
return mark_safe(class_re.sub(match.group(1) + " " + css_class,
string))
else:
return mark_safe(string.replace('>', ' class="%s">' % css_class, 1))
return value