简体   繁体   中英

Styling ModelMultipleChoiceField Django

I'm having trouble styling my django form with a ModelMultipleChoiceField.

Heres my form:

class SkriptenSelect(forms.Form):
skripten = StyledModelMultipleChoiceField(
    queryset=None,
    widget=forms.CheckboxSelectMultiple,
)

def __init__(self, *args, **kwargs):
    choices = kwargs.pop('choices')
    super(SkriptenSelect, self).__init__(*args, **kwargs)
    self.fields['skripten'].queryset = choices

class StyledModelMultipleChoiceField(forms.ModelMultipleChoiceField):
def label_from_instance(self, obj):
    return mark_safe('<ul class="list-inline" style="display: inline;">' \
                     '<li>{name}</li>' \
                     '<li>{semester}</li>' \
                     '<li>professor</li>' \
                     '</ul>'.format(name=escape(obj.name), semester=escape(obj.prefix))
                     )

And I used this for html:

<form action="." method="post">
  <ul class="list-group">
    {% for skript in result_form.skripten %}
        <li class="list-group-item">
            {{ skript }}
        </li>
    {% endfor %}
</ul>
{% csrf_token %}
<input type="submit" value="Submit Selected" />

This requires me to put my HTML in my forms file, which is not a very mvc way. Also it restricts me heavily in how i can style the list (ie making table of the model instance fields)

Is there anyway to make this smarter? I'd like to access {{ skript.name }}, {{ skript.checkbox }} or something in my {% for skript in result_form.skripten %} loop, but thats sadly not possible...

You can use render_to_string . It loads a template and renders it with a context. Returns a string.

from django.template.loader import render_to_string
rendered = render_to_string('my_template.html', {'foo': 'bar'})

For various variants you can make various StyledModelMultipleChoiceField subclasses OR pass the desired template_name when initialising the class. Eg:

>>> class FooField:
...     def __init__(self, template_name='default.html'):
...         self.template_name = template_name
...
>>> x = FooField('table.html')
>>> x.template_name
'table.html'

Use self.template_name where appropriate:

def label_from_instance(self, obj)
    return render_to_string(self.template_name, {'foo': obj.foo})

If you want to display multiple instances, use a formset .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM