Как мне создать следующее:
в forms.py -
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
в contact_form.html -
<form action="" method="post">
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit">
</form>
Например, как установить класс или идентификатор для темы, сообщения электронной почты, чтобы предоставить внешнюю таблицу стилей? Спасибо вам
Взятый из моего ответа на: Как пометить поля формы с < div class= 'field_type' > в Django
class MyForm(forms.Form):
myfield = forms.CharField(widget=forms.TextInput(attrs={'class' : 'myfieldclass'}))
или
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['myfield'].widget.attrs.update({'class' : 'myfieldclass'})
или
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'myfield': forms.TextInput(attrs={'class': 'myfieldclass'}),
}
--- EDIT ---
Вышеизложенное является самым простым изменением, чтобы сделать исходный код вопроса, который выполняет задание. Это также заставляет вас не повторять себя, если вы повторно используете форму в других местах; ваши классы или другие атрибуты просто работают, если вы используете методы формы Django as_table/as_ul/as_p. Если вам нужен полный контроль для полностью персонализированного рендеринга, это четко документировано
- ИЗМЕНИТЬ 2 ---
Добавлен новый способ указания виджета и attrs для ModelForm.
Это можно сделать с помощью настраиваемого фильтра шаблонов. учитывая, что вы делаете свою форму следующим образом:
<form action="/contact/" method="post">
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.subject.errors }}
{{ form.subject.label_tag }}
{{ form.subject }}
<span class="helptext">{{ form.subject.help_text }}</span>
</div>
</form>
form.subject - это экземпляр BoundField, у которого есть метод as_widget.
вы можете создать настраиваемый фильтр "addclass" в "my_app/templatetags/myfilters.py"
from django import template
register = template.Library()
@register.filter(name='addclass')
def addclass(value, arg):
return value.as_widget(attrs={'class': arg})
И затем примените свой фильтр:
{% load myfilters %}
<form action="/contact/" method="post">
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.subject.errors }}
{{ form.subject.label_tag }}
{{ form.subject|addclass:'MyClass' }}
<span class="helptext">{{ form.subject.help_text }}</span>
</div>
</form>
form.subjects будет отображаться с классом css "MyClass".
Надеюсь на эту помощь.
Если вы не хотите добавлять какой-либо код в форму (как указано в комментариях к @shadfc Answer), это, безусловно, возможно, вот два варианта.
Сначала вы просто ссылаетесь на поля отдельно в HTML, а не на всю форму сразу:
<form action="" method="post">
<ul class="contactList">
<li id="subject" class="contact">{{ form.subject }}</li>
<li id="email" class="contact">{{ form.email }}</li>
<li id="message" class="contact">{{ form.message }}</li>
</ul>
<input type="submit" value="Submit">
</form>
(Обратите внимание, что я также изменил его на несортированный список.)
Во-вторых, обратите внимание на документы вывод форм в формате HTML, Django:
Идентификатор поля, генерируется добавив 'id_' к имени поля. Идентификационные атрибуты и теги включается в выход по умолчанию.
Все поля формы уже имеют уникальный id. Таким образом, вы должны ссылаться на id_subject в вашем файле CSS, чтобы создать поле темы. Я должен отметить, так выглядит форма, когда вы берете HTML по умолчанию, который требует просто распечатать форму, а не отдельные поля:
<ul class="contactList">
{{ form }} # Will auto-generate HTML with id_subject, id_email, email_message
{{ form.as_ul }} # might also work, haven't tested
</ul>
См. предыдущую ссылку для других параметров при выводе форм (вы можете делать таблицы и т.д.).
Примечание. Я понимаю, что это не то же самое, что добавлять класс к каждому элементу (если вы добавили поле в форму, вам также нужно будет обновить CSS), но это достаточно просто, чтобы ссылаться на все полей по id в вашем CSS, например:
#id_subject, #id_email, #email_message
{color: red;}
Вы можете сделать следующее:
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
subject.widget.attrs.update({'id' : 'your_id'})
Надеюсь, что это работает.
Игнас
Вы можете использовать эту библиотеку: https://pypi.python.org/pypi/django-widget-tweaks
Это позволяет сделать следующее:
{% load widget_tweaks %}
<!-- add 2 extra css classes to field element -->
{{ form.title|add_class:"css_class_1 css_class_2" }}
render_field
.
В this в блоге вы можете добавлять классы css в свои поля, используя настраиваемый фильтр шаблонов.
from django import template
register = template.Library()
@register.filter(name='addcss')
def addcss(field, css):
return field.as_widget(attrs={"class":css})
Поместите это в свою папку templatetags/папку, и теперь вы можете сделать
{{field|addcss:"form-control"}}
Вы можете сделать:
<form action="" method="post">
<table>
{% for field in form %}
<tr><td>{{field}}</td></tr>
{% endfor %}
</table>
<input type="submit" value="Submit">
</form>
Затем вы можете добавить классы /id, например, в тег <td>
. Вы можете, конечно, использовать любые другие теги, которые вы хотите. Проверьте Работа с форматами Django в качестве примера того, что доступно для каждого field
в форме ({{field}}
, например, просто выводит тег ввода, а не ярлык и т.д.).
Не видел этого действительно...
https://docs.djangoproject.com/en/1.8/ref/forms/api/#more-granular-output
Методы as_p(), as_ul() и as_table() - это просто ярлыки для ленивых разработчиков - это не единственный способ отображения объекта формы.
класс BoundField Используется для отображения HTML или атрибутов доступа для одного поля экземпляра формы.
Метод str() ( unicode на Python 2) отображает HTML для этого поля.
Чтобы получить один BoundField, используйте синтаксис словарного поиска в форме, используя имя поля в качестве ключа:
>>> form = ContactForm()
>>> print(form['subject'])
<input id="id_subject" type="text" name="subject" maxlength="100" />
Чтобы получить все объекты BoundField, выполните итерацию формы:
>>> form = ContactForm()
>>> for boundfield in form: print(boundfield)
<input id="id_subject" type="text" name="subject" maxlength="100" />
<input type="text" name="message" id="id_message" />
<input type="email" name="sender" id="id_sender" />
<input type="checkbox" name="cc_myself" id="id_cc_myself" />
Результат, специфичный для поля, отличает настройку auto_id объекта формы:
>>> f = ContactForm(auto_id=False)
>>> print(f['message'])
<input type="text" name="message" />
>>> f = ContactForm(auto_id='id_%s')
>>> print(f['message'])
<input type="text" name="message" id="id_message" />
Вам не нужно переопределять класс формы __init__
, потому что Django устанавливает атрибуты name
и id
в HTML input
s. У вас может быть такой CSS:
form input[name='subject'] {
font-size: xx-large;
}
id
созданное Django для наборов форм, становится довольно волосатым…
Существует очень простой в установке и отличный инструмент для Django, который я использую для стилизации, и его можно использовать для всех интерфейсных фреймворков, таких как Bootstrap, Materialize, Foundation и т.д. Это называется виджетами-настройками. Документация: Widget Tweaks
из форм импорта django
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
Вместо использования значения по умолчанию:
{{ form.as_p }} or {{ form.as_ul }}
Вы можете отредактировать его по-своему, используя атрибут render_field, который дает вам более html-способ стилизации, как в этом примере:
template.html
{% load widget_tweaks %}
<div class="container">
<div class="col-md-4">
{% render_field form.subject class+="form-control myCSSclass" placeholder="Enter your subject here" %}
</div>
<div class="col-md-4">
{% render_field form.email type="email" class+="myCSSclassX myCSSclass2" %}
</div>
<div class="col-md-4">
{% render_field form.message class+="myCSSclass" rows="4" cols="6" placeholder=form.message.label %}
</div>
</div>
Эта библиотека дает вам возможность хорошо отделить ваш интерфейс от вашего бэкэнда
Одним из решений является использование JavaScript для добавления необходимых классов CSS после того, как страница будет готова. Например, стиль django формирует вывод с помощью классов начальной загрузки (jQuery используется для краткости):
<script type="text/javascript">
$(document).ready(function() {
$('#some_django_form_id').find("input[type='text'], select, textarea").each(function(index, element) {
$(element).addClass("form-control");
});
});
</script>
Это позволяет избежать уродства, связанного с детализацией стилей в вашей бизнес-логике.
В Django 1.10 (возможно, и раньше) вы можете сделать это следующим образом.
Модель:
class Todo(models.Model):
todo_name = models.CharField(max_length=200)
todo_description = models.CharField(max_length=200, default="")
todo_created = models.DateTimeField('date created')
todo_completed = models.BooleanField(default=False)
def __str__(self):
return self.todo_name
форма:
class TodoUpdateForm(forms.ModelForm):
class Meta:
model = Todo
exclude = ('todo_created','todo_completed')
Шаблон:
<form action="" method="post">{% csrf_token %}
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.todo_name.errors }}
<label for="{{ form.name.id_for_label }}">Name:</label>
{{ form.todo_name }}
</div>
<div class="fieldWrapper">
{{ form.todo_description.errors }}
<label for="{{ form.todo_description.id_for_label }}">Description</label>
{{ form.todo_description }}
</div>
<input type="submit" value="Update" />
</form>