23👍
To solve this I made my own template filter, you can apply it on any tag, not just input elements!
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))
return value
52👍
You only need to install Django widget_tweaks
pip install django-widget-tweaks
After you can to do something like that on your template:
{{ form.search_query|attr:"type:search" }}
—
Read all about it here.
- [Django]-How to add a cancel button to DeleteView in django
- [Django]-How to force Django models to be released from memory
- [Django]-Get distinct values of Queryset by field
19👍
Another way is to use the as_widget
method on a field to alter it — simpler and safer than the regex approach, and doesn’t require any additional dependencies.
Define a custom template filter:
@register.filter
def add_class(field, class_name):
return field.as_widget(attrs={
"class": " ".join((field.css_classes(), class_name))
})
And in your template:
{{ form.first_name|add_class:"span-4" }}
You can also use as_widget
to add other attributes, like placeholder
, etc.
- [Django]-Django multi-select widget?
- [Django]-How to clear the whole cache when using django's page_cache decorator?
- [Django]-Django: Display current locale in a template
12👍
A few extra notes on how to get going with Lazerscience’s very handy solution. Here’s how the file looks with dependency imports:
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))
return value
I pasted this into a file called add_class.py. The directory structure is:
mydjangoproject > general_tools_app > templatetags > add_class.py
general_tools_app is an application which collects useful functionality like this that I add to new django projects.
(The general_tools_app and templatetags directories both have an empty __init__.py
file so that they get registered correctly)
In settings.py, my INSTALLED_APPS tuple includes the entry ‘mydjangoproject.general_tools_app’.
To use the filter in a template, I add the line {% load add_class %}
at the top of the file. If I want to add the class ‘delete’ to a field, I’d do this
{{ myfield|add_class:'delete' }}
- [Django]-Django get a QuerySet from array of id's in specific order
- [Django]-Django-Admin: CharField as TextArea
- [Django]-Django Selective Dumpdata
4👍
I am still learning Django, but couldn’t you do this something like this –
from django import forms
class SomeForm(forms.Form):
f = forms.CharField(label='x',widget=forms.TextInput(attrs={'class':'name'}))
I guess there is no need to do this at the template level (or use filters) unless you have some requirement that I did not understand.
- [Django]-How to add an model instance to a django queryset?
- [Django]-Celery unable to use redis
- [Django]-Cannot install psycopg2 Ubuntu
3👍
One more note on lazerscience’s solution: if you apply this to a <select> element with no class attribute, the string replace in the else case would produce something like this:
<select name="state" id="id_state" class="class1 class2">
<option value="AL" class="class1 class2">Alabama</option class="class1 class2">
<option value="AK" class="class1 class2">Alaska</option class="class1 class2">
<option value="AZ" class="class1 class2">Arizona</option class="class1 class2">
</select class="class1 class2">
I’m pretty sure browsers scrap those extraneous class definitions, but that’s a lot of string replaces when you only need one. An easy remedy for this:
return mark_safe(string.replace('>', ' class="%s">' % css_class, 1))
That last argument (1) will ensure that only the first instance of “>” will be replaced with “class=”…”>, which is logically correct for any form element.
- [Django]-Switching to PostgreSQL fails loading datadump
- [Django]-How to use Cassandra in Django framework
- [Django]-How to get username from Django Rest Framework JWT token
0👍
You need to specify the widget explicitly and add the class using the attrs
keyword argument. There is no other way that I know of.
However, if this is too cumbersome, you could still just wrap the field in another element, such as div or span and add a class to that. Then modify your CSS accordingly.
- [Django]-Django content-type : how do I get an object?
- [Django]-Django – getting Error "Reverse for 'detail' with no arguments not found. 1 pattern(s) tried:" when using {% url "music:fav" %}
- [Django]-Django Model Field Default to Null
0👍
Updated for python3
It was simple to update, just needed parenthesis on the print and a change of unicode(value) to str(value), I also just quickly changed the ‘ class=”%s”>’ to an fstring.
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 = str(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('>', f' class="{css_class}">'))
return value
- [Django]-Django Query That Get Most Recent Objects From Different Categories
- [Django]-Django: How to rollback (@transaction.atomic) without raising exception?
- [Django]-How to express a One-To-Many relationship in Django?