Я пытаюсь создать виджет CheckboxSelectMultiple, в котором перечислены все типы содержимого моего проекта.Я начал с использования базового виджета при определении поля MultipleChoiceField в ModelForm, и он работал нормально.Теперь я хотел бы сделать его пользовательским виджетом, который я могу импортировать через приложение в любой проект.
Вот код, который я использую:
# myapp/models.py
from django.db import models
class Tiger(models.Model):
color = models.CharField(max_length=100)
# myapp/admin.py
from django import forms
from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from myapp.models import Tiger
class TigerForm(forms.ModelForm):
"""
Default ModelForm that will be overriden.
"""
class Meta:
model = Tiger
Здесь я определяю свой пользовательский виджет.виджет.Я предполагаю, что неправильно передаю список значений (см. Комментарий в коде).
class TigerWidget(forms.CheckboxSelectMultiple):
"""
Custom widget that displays a list of checkboxes for each content type.
The goal is to make it generic enough to put it in an external app
that can be imported into any project.
"""
def __init__(self, attrs=None, choices=()):
# List all content types
content_types = ContentType.objects.all()
classes = tuple([(c.model, c.name) for c in content_types])
# Define widget choices as the list of these content types
self.choices = classes # I am guessing it should be done differently?
# Select all of them by default
self.initial = [c[0] for c in classes]
# Same behavior as parent
super(TigerWidget, self).__init__(attrs)
Вот остальные классы, которые его используют.
class TigerCustomForm(TigerForm):
"""
Custom form that adds a field using the custom widget to the form.
"""
# content_types = ContentType.objects.all()
# classes = tuple([(c.model, c.name) for c in content_types])
# This works fine.
# nickname = forms.MultipleChoiceField(
# widget=forms.CheckboxSelectMultiple,
# choices=classes,
# # Select all by default
# initial=[c[0] for c in classes]
# )
# This does not. An empty list (<ul></ul>) is rendered in the place of the widget.
nickname = forms.MultipleChoiceField(
widget=TigerWidget,
)
class TigerAdmin(admin.ModelAdmin):
form = TigerCustomForm
admin.site.register(Tiger, TigerAdmin)
admin.site.register(ContentType)
Спасибозаранее за вашу помощь.