Django: Як додати довільні атрибути html у поля введення форми?


101

У мене є поле введення, яке відображається з таким шаблоном:

<div class="field">
   {{ form.city }}
</div>

Що відображається як:

<div class="field">
    <input id="id_city" type="text" name="city" maxlength="100" />
</div>

Тепер припустимо, що я хочу додати autocomplete="off"атрибут до введеного елементу, як це зробити? Або onclick="xyz()"чи class="my-special-css-class"?

Відповіді:


126

Перевірте цю сторінку

city = forms.CharField(widget=forms.TextInput(attrs={'autocomplete':'off'}))

2
Добре, дякую. У моєму випадку я використовую ModelForm, тому я чітко не визначаю поля форми (наприклад, клас AddressForm (form.ModelForm): клас Meta: model = models.Adress) Чи означає це, що я не можу використовувати ModelForm або є щось особливе потрібно робити?
Користувач


1
@InfinitelyLoopy всередині init for form ви можете додати код, щоб захопити поле та змінити його атрибути віджетів. Ось декілька я використовував раніше для зміни 3 полів: `` `для field_name у ['image', 'image_small', 'image_mobile']: field = self.fields.get (field_name) field.widget.attrs ['data- file '] =' файл '`` `
Стюарт Ексон

4
А як щодо атрибутів, які не беруть аргументів, таких як "потрібно" та "автофокусувати"?
Вільгельм Клопп

1
Це рішення є поганим, оскільки немає роз'єднання проблем. Атрибути HTML не повинні записуватися в код python IMO. Рішення Михайла Коробова є вищим.
Девід Д.

115

Вибачте за рекламу, але нещодавно я випустив додаток ( https://github.com/kmike/django-widget-tweaks ), який робить такі завдання ще менш болючими, тому дизайнери можуть це робити, не торкаючись коду пітона:

{% load widget_tweaks %}
...
<div class="field">
   {{ form.city|attr:"autocomplete:off"|add_class:"my_css_class" }}
</div>

або, альтернативно,

{% load widget_tweaks %}
...
<div class="field">
   {% render_field form.city autocomplete="off" class+="my_css_class" %}
</div>

3
Гарний додаток Майк, саме те, що я шукав!
jmagnusson

документація не каже вам додавати "widget_tweaks" у встановлену програму в налаштуваннях, можливо, варто поставити це в документацію.
Джеймс Лін

Привіт Джеймс, це не підкреслено, але в розділі "Установка" вже є примітка про додавання "widget_tweaks" до INSTALLED_APPS.
Михайло Коробов

@MikhailKorobov дуже дякую за це додаток, воно мені дуже допомогло! Це було саме те, що я шукав. Мені потрібна форма від ModelForm, і я не хотів вручну вставляти ці атрибути в кожне поле (40 з них), тому мені елегантно вдалося досягти однакового результату за секунди :) Це має бути прийнятою відповіддю!
Любіса Лівак

Я планував написати таку заяву. Завдяки економії моїх зусиль.
Ануй ТБЕ

31

Якщо ви використовуєте "ModelForm":

class YourModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(YourModelForm, self).__init__(*args, **kwargs)
        self.fields['city'].widget.attrs.update({
            'autocomplete': 'off'
        })

3
Добре! Зараз немає необхідності чітко визначати всі віджети.
Мікаел Ліндльоф

20

Якщо ви використовуєте ModelForm, окрім можливості використання __init__як @Artificioo, передбаченої у його відповіді, widgetsу Meta для цього питання є словник:

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ('name', 'title', 'birth_date')
        widgets = {
            'name': Textarea(attrs={'cols': 80, 'rows': 20}),
        }

Відповідна документація


1
Намагаючись розібратися, чому це отримало менше результатів, ніж відповідь вище ... іноді я думаю, що розробники Django / Python просто віддають перевагу більш складний спосіб робити справи
trpt4him

@ trpt4him Використання підходу init корисно для створення класу Mixin або Base, який можна повторно використовувати в інших формах. Це характерно для середнього та масштабного проекту. Meta.widgets чудово підходить для однієї форми. Отже, обидва є гарними відповідями.
Ахорус

2

Я не хотів використовувати для цієї речі цілий додаток. Натомість тут я знайшов такий код https://blog.joeymasip.com/how-to-add-attributes-to-form-widgets-in-django-templates/

# utils.py
from django.template import Library
register = Library()

@register.filter(name='add_attr')
def add_attr(field, css):
    attrs = {}
    definition = css.split(',')

    for d in definition:
        if ':' not in d:
            attrs['class'] = d
        else:
            key, val = d.split(':')
            attrs[key] = val

    return field.as_widget(attrs=attrs)

використовувати тег у файлі html

{% load utils %}
{{ form.field_1|add_attr:"class:my_class1 my_class2" }}
{{ form.field_2|add_attr:"class:my_class1 my_class2,autocomplete:off" }}

0

Вигляд і відображення остаточної формиЯ витратив досить багато днів, намагаючись створити шаблони форм для повторного використання для створення та оновлення моделей у формах Джанго. Зауважте, що я використовую ModelForm для зміни або створення об'єкта. Я також використовую завантажувальний стиль для оформлення моїх форм. Раніше я використовував django_form_tweaks для деяких форм, але мені потрібна була якась налаштування без великої залежності від шаблону. Оскільки в моєму проекті вже є jQuery, я вирішив використовувати його властивості для стилювання моїх форм. Ось код і може працювати з будь-якою формою.

#forms.py
from django import forms
from user.models import User, UserProfile
from .models import Task, Transaction

class AddTransactionForm(forms.ModelForm):
    class Meta:
       model = Transaction
       exclude = ['ref_number',]
       required_css_class = 'required'

Views.py

@method_decorator(login_required, name='dispatch')
class TransactionView(View):
def get(self, *args, **kwargs):
    transactions = Transaction.objects.all()
    form = AddTransactionForm
    template = 'pages/transaction.html'
    context = {
        'active': 'transaction',
        'transactions': transactions,
        'form': form
    }
    return render(self.request, template, context)

def post(self, *args, **kwargs):
    form = AddTransactionForm(self.request.POST or None)
    if form.is_valid():
        form.save()
        messages.success(self.request, 'New Transaction recorded succesfully')
        return redirect('dashboard:transaction')
    messages.error(self.request, 'Fill the form')
    return redirect('dashboard:transaction')

HTML-код Примітка: Я використовую модаль bootstrap4 для видалення клопоту створення багатьох переглядів. Можливо, краще використовувати загальні CreateView або UpdateView. Посилання Bootstrap та jqQery

 <div class="modal-body">
    <form method="post" class="md-form" action="." enctype="multipart/form-data">
      {% csrf_token %}
      {% for field in form %}
      <div class="row">
        <div class="col-md-12">
          <div class="form-group row">
            <label for="" class="col-sm-4 col-form-label {% if field.field.required %}
            required font-weight-bolder text-danger{%endif %}">{{field.label}}</label>
            <div class="col-sm-8">
              {{field}}
            </div>

          </div>
        </div>
      </div>

      {% endfor %}

      <input type="submit" value="Add Transaction" class="btn btn-primary">
    </form>
  </div>

Код Javascript не забудьте завантажити цю $(document).ready(function() { /* ... */});функцію.

var $list = $("#django_form :input[type='text']");
$list.each(function () {
    $(this).addClass('form-control')
  });
  var $select = $("#django_form select");
  $select.each(function () {
    $(this).addClass('custom-select w-90')
  });
  var $list = $("#django_form :input[type='number']");
  $list.each(function () {
    $(this).addClass('form-control')
  });
  var $list = $("form :input[type='text']");
  $list.each(function () {
    $(this).addClass('form-control')
  });
  var $select = $("form select");
  $select.each(function () {
    $(this).addClass('custom-select w-90')
  });
  var $list = $("form :input[type='number']");
  $list.each(function () {
    $(this).addClass('form-control')
  });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.