ManyToMany フィールドを持つ ModelForm があります。このフィールド用のカスタム ウィジェットを作成し、CheckboxSelectMultiple をサブクラス化しました。編集用ではなく、ModelForm で m2m リレーションからフィールドを表示したいと思います。コードのインデントがめちゃくちゃになって申し訳ありません。
models.py
class Feed(models.Model):
name = models.CharField(max_length=200)
url = models.URLField()
description = models.TextField(blank=True)
category = models.ForeignKey('categories.Category', blank=True, null=True)
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Feed, self).save(*args, **kwargs)
class List(models.Model):
name = models.CharField(max_length=200)
owner = models.ForeignKey(settings.AUTH_USER_MODEL)
feeds = models.ManyToManyField(Feed)
category = models.ForeignKey('categories.Category', blank=True, null=True)
def __unicode__(self):
return self.name
ビュー.py
class ListCreateView(LoginRequiredMixin, UserFormKwargsMixin, FeedsActionMixin,
CreateView):
model = List
form_class = forms.ListCreateForm
def get_context_data(self, **kwargs):
context = super(ListCreateView, self).get_context_data(**kwargs)
context['form'] = forms.ListCreateForm()
return context
フォーム.py
class FeedListWidget(forms.CheckboxSelectMultiple):
class Media:
css = {
'all': ('css/feed_list_style.css',)
}
js = ('js/feed_list.js')
def __init__(self, attrs={}):
super(FeedListWidget, self).__init__(attrs)
feeds = Feed.objects.all()
classes = tuple([(c.id, c.name, c.description) for c in feeds])
self.choices = classes
def render(self, name, value, attrs=None, choices=()):
output = super(FeedListWidget, self).render(name, values, attrs, choices)
return output
class ListCreateForm(UserKwargModelFormMixin, forms.ModelForm):
feeds = forms.ModelMultipleChoiceField(
queryset=Feed.objects.all(), widget=FeedListWidget())
class Meta:
model = List
fields = ['name','feeds']
widgets = {
'name': forms.TextInput,
'feeds': FeedListWidget,
}
def __init__(self, *args, **kwargs):
super(ListCreateForm, self).__init__(*args, **kwargs)
owner = self.user
self.helper = FormHelper(self)
self.helper.form_method = 'POST'
self.helper.layout = Layout(
Fieldset(
'',
HTML("""
<p>Create a List here</p>
"""),
'name',
),
Field('feeds', template="feeds/feeds_select.html"),
)
self.helper.add_input(Submit('save', 'save'))
return super(ListCreateForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
list = super(ListCreateForm, self).save(commit=False)
list.owner = self.user
if commit:
list.save()
self.save_m2m()
return list
feeds_select.html
{% load debug_tags %}
<div class="controls"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
{% include 'bootstrap/layout/field_errors_block.html' %}
{% for choice in field.field.choices %}
<div class="feed row">
<div class="feed-icon span1"></div>
<div class="feed-name span5">{{ choice.1 }}
<div class="feed-description"></div>
</div>
<div class="description-toggle span2">See More</div>
<label class="checkbox{% if inline_class %} {{ inline_class }}{% endif %} span1">
<div class="add-btn">Add</div>
<input type="checkbox"{% if choice.0 in field.value or choice.0|stringformat:"s" in field.value or choice.0|stringformat:"s" == field.value|stringformat:"s" %} checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ field.html_name }}_{{ forloop.counter }}" value="{{ choice.0 }}">
</label>
</div>
{% endfor %}
{% include 'bootstrap/layout/help_text.html' %}
</div>
django-crispy-forms を使用してフォームのレイアウトを処理していることに注意してください。これが何かに影響するかどうかはわかりません。したがって、私の ListCreateForm では、フィードの説明とその名前にアクセスしたいと思います。「field.field.choices」変数からアクセスする方法はありますか? モデルの unicode 関数に含めることができることはわかっていますが、jquery で非表示/公開するため、テンプレート タグとしてアクセスしたいと考えています。
私はこれについて間違った方法で進んでいますか?これに直接関連する質問を見つけることができず、モデルフォームとその操作に関する回答をまとめるのに苦労しています. どんな助けや指導も大歓迎です。