我有一个具有 ManyToMany 字段的 ModelForm。我为这个字段创建了一个自定义小部件,继承了 CheckboxSelectMultiple。我想在我的 ModelForm 中显示来自 m2m 关系的字段,而不是用于编辑。抱歉,代码缩进搞砸了。
模型.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 上,我想访问 Feed 的描述及其名称。有没有办法让我从“field.field.choices”变量中访问它?我知道我可以将它包含在我的模型 unicode 函数中,但我想将它作为模板标签访问,因为我将使用 jquery 隐藏/显示它。
我会以错误的方式解决这个问题吗?我无法找到与此直接相关的任何问题,并且很难将有关模型形式及其操作的答案拼凑在一起。非常感谢任何帮助或指导。