我有一个ModelForm,它有一个ManyToMany字段。我为这个字段创建了一个自定义小部件,继承了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
views.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
forms.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上,我想访问Feed的描述及其名称。有没有办法让我从“field.field.choices”变量访问它?我知道我可以将它包含在我的模型unicode函数中,但我希望将其作为模板标记访问,因为我将使用jquery隐藏/显示它。
我是以错误的方式来做这件事的吗?我无法找到与此直接相关的任何问题,并且很难拼凑出有关模型及其操作的答案。非常感谢任何帮助或指导。