在Django Template中隐藏ModelForms中的外键字段

时间:2016-01-13 20:09:02

标签: python django forms templates models

以下内容。 我有一些不同的杂志。模板中的AutoForm显示所有文章和所有作者的可能选择(不仅来自当前杂志)。如何限制作者的这一选择仅限于当前的杂志?我可以只使用模板吗?如果没有,那怎么样?

models.py

class Magazine(models.Model):
    Name = models.CharField(max_length=200)

class Article(models.Model):
    Name = models.CharField(max_length=200)
    Magazine = models.ForeignKey(Magazine)

class Author(models.Model):
    Name = models.CharField(max_length=200)
    Magazine = models.ForeignKey(Magazine)

class Sets(models.Model):
    Name = models.CharField(max_length=200)
    Magazine = models.ForeignKey(Magazine)
    Aut = models.ManyToManyField(Author, null=True, blank=True)
    Set = models.ForeignKey(Article, null=True, blank=True)

forms.py:

class MagazineForm(ModelForm):
    class Meta:
        model = Magazine
        fields = {'Name'}

class ArticleForm(ModelForm):
    class Meta:
        model = Article
        fields = {'Name'}

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = {'Name'}

class SetsForm(ModelForm):
    class Meta:
        model = Sets
        fields = {'Name', 'Set', 'Aut'}

views.py

def building_details(request, magazine_id):
    sets_form = SetsForm
    args = {}
    args.update(csrf(request))
    args['magazine'] = Magazine.objects.get(id=magazine_id)
    args['article'] = Article.objects.filter(Magazine=magazine_id)
    args['author'] = Author.objects.filter(Magazine=magazine_id)
    args['sets'] = Sets.objects.filter(Magazine=magazine_id)
    args['setform'] = sets_form
    return render_to_response('building.html', args)

模板

<form action='/add/{{ magazine.id }}/' method='post'>
{% csrf_token %}
{{ setform }}
<input type='submit' class='button' value="Добавить">
</form>
</div>

也许在这个条目的某个地方有错误(我简要编辑,删除不在这里扮演一个角色,基本上)。总的来说,除了显示所有对象外,我还能正常工作,而不是仅显示当前对象。

2 个答案:

答案 0 :(得分:0)

听起来你正试图根据某些标准限制ForeignKey选择器中的选项。

这意味着您需要覆盖表单__init__方法中的一些细节:

class SetsForm(ModelForm):
    class Meta:
        model = Sets
        fields = {'Name', 'Set', 'Aut'}

    def __init__(self, *args, **kwargs):
        articles = Article.objects.filter(Magazine=kwargs.pop('magazine_id'))
        super(SetsForm, self).__init__(*args, **kwargs)
        self.fields['articles'] = forms.ModelChoiceField(
            queryset=articles ,
            label="Articles",
        )

然后像这样打电话给你的表格:

sets_form = SetsForm(magazine_id=magazine_id)

答案 1 :(得分:0)

仅在当前杂志中获取文章的作者:

articles = Article.objects.filter(Magazine=magazine_id)
sets = Sets.objects.filter(Magazine=magazine_id, Set__in=articles)

import itertools
# build a flat list of all Authors in these sets (and call `set` to avoid duplicates)
authors = set(itertools.chain(*[s.Aut.all() for s in sets]))

如果作者对文章有直接外键,这将更容易。

此外,您应该使用小写字段名称​​遵循Django约定。这样可以避免使用大写的字段和模型之间的混淆。