Доступ к атрибутам элемента формы в шаблоне Django - PullRequest
0 голосов
/ 04 февраля 2020

Как мне получить доступ к атрибуту элемента ввода, скажем, aria-describedby, в Django синтаксисе шаблона?

Как показано ниже, в шаблоне я могу получить доступ к метке как {{form.email.label}}, но как это сделать? Я получаю атрибут aria-describedby?

<!-- Django 2.2.9 -->
<form method="POST">
    {% csrf_token %}
    <label for="{{ form.email.id_for_label }}">{{form.email.label}}</label>
    {{ form.email }}
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

Файл form.py указан ниже.

# Django 2.2.9
from django import forms

class ExampleForm(forms.Form):
    email = forms.EmailField(
          label="Email address",
          widget=forms.EmailInput(
              attrs = {
                  "class":"form-control",
                  "placeholder":"Enter email",
                  "aria-describedby":"EmailHelp"
              }
           )
      )

Используя {{ form.email }} в шаблоне, код указан в forms.py будет визуализировать элемент ввода, как показано ниже.

<input type="email" name="email" class="form-control" 
placeholder="Enter email" aria-describedby="EmailHelp" required id="id_email">

Было бы удобно, если бы можно было получить доступ к атрибуту aria-describedby, используя некоторый код, такой как {{form.email.aria_describedby}}.

Примечания

  1. Есть другой аналогичный вопрос о SO, предлагающий использовать синтаксис, такой как {{form.email.widget.attrs.placeholder}}, , однако в Django 2.2.9 это не так работа . Комментарий: Нет, этот синтаксис работает в Django 2.2.9. Проблема заключается в использовании специальных символов, таких как дефисы.

  2. Я бы предпочел не использовать дополнительные пакеты, такие как Crispy формы.

Дополнительные коды кода

views.py

# Djano 2.2.9
from django.shortcuts import render,redirect
from . forms import ExampleForm

def contact(request):

    if request.method == "POST":
        return redirect('example-index')

    form = ExampleForm()
    context = {'form':form}

    return render(request,'example/index.html',context)

index. html

<!-- Django 2.2.9 -->
<form method="POST">
    {% csrf_token %}
    <label for="{{ form.email.id_for_label }}">{{form.email.label}}</label>
    {{ form.email }}
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

<h2>Accessing form field attributes in the Django template</h2>

<p><code>form.email.label</code>
         =  {{form.email.label}} </p>

<p><code>form.email.id_for_label</code>
         =  {{form.email.id_for_label}} </p>

<p><code>form.email.aria_describedby</code>
         = {{form.email.aria_describedby}} </p>

<p><code>form.email.widget.attrs.class</code>
         = {{form.email.widget.attrs.class}} </p>

urls.py

# Django 2.2.9
from django.urls import path
from . import views

urlpatterns= [
    path('',views.contact, name="example-index"),
]

1 Ответ

0 голосов
/ 05 февраля 2020

После дополнительных исследований проблемы, представленной в вопросе, я нашел решение и решил написать его здесь.

Доступ к атрибутам формы ввода с использованием Django синтаксиса шаблона находятся в все случаи просты, кроме случаев, когда ключ содержит специальный символ, например дефис -. Например, все атрибуты, указанные в файле forms.py, указанном в вопросе, доступны в шаблоне Django, как показано ниже

<!-- Django 2.2.9 template file -->
<p>0. {{form.email}}</p>
<p>1. {{form.email.field.label}}</p>
<p>2. {{form.email.field.max_length}}</p>
<p>3. {{form.email.field.widget.attrs.class}}</p>
<p>4. {{form.email.field.widget.attrs.placeholder}}</p>

На изображении ниже показано отображение в веб-браузере.

Screen capture of the web browser

Однако доступ к атрибуту aria-describedby более сложен, так как используется дефис, специальный символ. Решение состоит в том, чтобы написать собственный шаблонный фильтр, например, с именем get_key_value, и в шаблоне вызвать фильтр, используя символ канала, например {{form.email.field.widget.attrs|get_key_value:"aria-describedby"}}

Пользовательский шаблонный фильтр

Здесь мой план написания настраиваемого фильтра шаблонов, в основном на основе Django документации :

a. Добавить папку в каталог приложения с именем templatetags и в этой папке добавьте два файла, пустой файл с именем __init__.py и файл с именем myapp_extras.py.

b. Добавьте следующий код в myapp_extras.py.

# Django 2.2.9
from django import template

register = template.Library()

@register.filter(name="get_key_value")
def get_key_value(some_dict,key):
    return some_dict.get(key,'')

c. В settings.py добавить фильтр в список установленных приложений. Обратите внимание, я назвал свое приложение myapp, также добавленное в список.

# Django 2.2.9
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
    'myapp.templatetags.myapp_extras'
]

D. Загрузите пользовательские фильтры в шаблон и примените фильтр get_key_value

<!-- Django 2.2.9 template file -->
{% load myapp_extras %}

<p>0. {{form.email}}</p>
<p>1. {{form.email.field.label}}</p>
<p>2. {{form.email.field.max_length}}</p>
<p>3. {{form.email.field.widget.attrs.class}}</p>
<p>4. {{form.email.field.widget.attrs.placeholder}}</p>

<p>5. {{form.email.field.widget.attrs|get_key_value:"aria-describedby"}}</p>

В браузере это выглядит так, как показано ниже, обратите внимание на пункт 5, где значение ключа aria-describedby отображается как EmailHelp.

enter image description here

...