Django Рендеринг пользовательских виджетов - PullRequest
0 голосов
/ 24 сентября 2018

Общая проблема

Предположим, у вас есть определенная модель

class MyModel(models.Model):
    Name = models.CharField(max_length=64)

и вспомогательная форма, которую вы используете для создания

class CreateMyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['name']

В обычной ситуации, когдаформа отображается в шаблоне Я обычно зацикливаюсь на полях в шаблоне

{%for field in form%}
{{field}}
{%endfor%}

Когда требуется пользовательский стиль, мне обычно приходится прибегать к размещению <div> s и<span> s в этом цикле и укажите базовый виджет и его attrs в подклассе Meta.

Просматривая документацию Django по теме, я понимаю, что мне кажется, что мне нужно поиграть с подклассом Media, чтобы все манипуляции происходили в свойстве widgets вMeta, но я просто не могу обернуть голову вокруг него.

Определенная проблема

Предположим, у меня есть шаблон, где TextInput формы должны отображать , как в этомtemplate :

<div class="form-group input-group">
    <span class="input-group-addon">Name</span>
        <input type="text" name="name" class="form-control" placeholder="MyModel Name">
</div>

Как мне создать виджет, чтобы получить тот же результат, используя:

class CreateMyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['name']
        widgets={'name':MyWidget(addon="Name",placeholder="MyModel Name")}

Я понимаю, что заполнитель - это то, что яможет поставить attrs инициализацию TextInput, но аддон (или родительский div в данном случае) не или, по крайней мере, не так, как мне известно

Я прошу прощения задлинный вопрос, я просто почувствовал, что мне нужно подробно объяснить эту проблему, потому что она беспокоит меня некоторое время ...

1 Ответ

0 голосов
/ 24 сентября 2018

Мы можем сделать, как показано ниже.

Виджет

from django import forms
from django.template import loader
from django.utils.safestring import mark_safe


class MyWidget(forms.Widget):
    template_name = 'widget_template.html'

    def get_context(self, name, value, attrs=None):
        return {'widget': {
            'name': name,
            'value': value,
        }}

    def render(self, name, value, attrs=None):
        context = self.get_context(name, value, attrs)
        template = loader.get_template(self.template_name).render(context)
        return mark_safe(template)

widget_template.html

<div class="form-group input-group">
    <span class="input-group-addon">Name</span>
        <input type="text" class="form-control" id="mywidget-{{ widget.name }}" name="{{ widget.name }}" />
</div>
...