简体   繁体   English

在Django模板中隐藏来自ModelForms的外键字段

[英]Hiding foreign key fields from ModelForms in Django Template

Essence in the following. 精华在以下。 I have a few different Magazine. 我有一些不同的杂志。 And AutoForm from template shows all Articles and all Authors for possible selection (not only from current Magazine). 模板中的AutoForm会显示所有文章和所有作者以供选择(不仅限于当前杂志)。 How to restrict this choice of author a for article only from the current magazine? 如何限制作者只选择当前杂志上的文章? Can I do this using only the Template? 我可以只使用模板吗? If not, then how? 如果没有,那怎么办?

models.py 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: 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 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)

Template 模板

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

Maybe somewhere in this entry there are errors (I briefly edited, removing not playing a role here, essentially). 也许在此条目中的某处存在错误(我进行了简要编辑,从本质上删除了在这里没有扮演的角色)。 In General I have everything working right, except that all objects are displayed, instead of only having the current. 总的来说,我可以正常工作,只是显示所有对象,而不是仅显示当前对象。

Sounds like you are trying to restrict the options in the ForeignKey selector based on some criteria. 听起来您正在尝试基于某些条件来限制ForeignKey选择器中的选项。

This means you need to override some of the details in the forms __init__ method: 这意味着您需要重写__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",
        )

Then call your form like so: 然后像这样调用您的表单:

sets_form = SetsForm(magazine_id=magazine_id)

To get authors of articles only in the current magazine: 若要仅在当前杂志上获得文章作者:

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]))

This would be easier if there were a direct foreign key on Author to Article. 如果在“文章作者”中有直接的外键,则这样做会更容易。

Also, you should follow Django convention by using lowercase field names. 另外,您应该使用小写的字段名称来遵循Django约定 This will avoid confusion between fields and models, which use uppercase. 这将避免使用大写字母的字段和模型之间的混淆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM