Django外键查询集表单

时间:2014-10-26 21:19:40

标签: django django-models django-forms

我有一张订购单,其中有几件商品可供购买。这些项目(年度,问题和文章)使用外键附加到Catalog对象。我想更改表单模型中的查询集以显示附加项而不是目录名。我是Django的新手,有没有办法在表单中构造这种类型的查询集?我已经为每个模型添加了默认查询集的模型。

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, ButtonHolder, Submit
from subscriber.models import Catalog

from . import models

class OrderListForm(forms.ModelForm):


p = Catalog.objects.get()
annuals = forms.ModelChoiceField(queryset=Catalog.objects.all())
issues = forms.ModelChoiceField(queryset=Catalog.objects.all())
articles = forms.ModelChoiceField(queryset=Catalog.objects.all())

class Meta:
    fields = (
                'annuals',
                'issues',
                'articles',)
    model = models.Order


def __init__(self, *args, **kwargs):
    super(OrderListForm, self).__init__(*args, **kwargs)
    self.helper = FormHelper()
    self.helper.layout = Layout(
        'annuals',
                'issues',
                'articles',
        ButtonHolder(
            Submit('create', 'Create')

        )


    )

这是我的模特:

class Catalog(models.Model):
products = models.CharField(max_length=200)

def __unicode__(self):
    return self.products

class Issue(models.Model):
    catalog = models.ForeignKey(Catalog, related_name='issue_products')
    Volume = models.DecimalField(max_digits=3, decimal_places=1)

    def __unicode__(self):
        return unicode(self.catalog)


class Annual(models.Model):
    catalog = models.ForeignKey(Catalog, related_name='annual_products')
    year_id = models.IntegerField(max_length=4)
    start_date = models.CharField(max_length=6)
    end_date = models.CharField(max_length=6)
    def __unicode__(self):
        return unicode(self.year_id)


class Annual_Issue(models.Model):
    annual_id = models.ForeignKey(Annual, related_name='annual_ids')
    issue_id = models.ForeignKey(Issue, related_name='issues')
    def __unicode__(self):
        return self.annual_id


class Article(models.Model):
    catalog = models.ForeignKey(Catalog, related_name='article_products')
    title = models.CharField(max_length=200)
    abstract = models.TextField(max_length=1000, blank=True)
    full_text = models.TextField(blank=True)
    proquest_link = models.CharField(max_length=200, blank=True, null=True)
    ebsco_link = models.CharField(max_length=200, blank=True, null=True)

    def __unicode__(self):
        return self.title


class Order(models.Model):
    user = models.ForeignKey(User, related_name='who_ordered')
    order_lines = models.ForeignKey(Issue, related_name='items_ordered')

1 个答案:

答案 0 :(得分:2)

您在表单中声明的​​ModelChoiceField都使用了不正确的queryset参数。在文档here中,您可以看到给ModelChoiceForm的查询集应该是一个查询集,从中可以填充字段中的选项:

  

模型对象的QuerySet,将从中导出字段的选项,并将用于验证用户的选择。

在您的示例中,您已将外键关系的错误结尾声明为每个ModelChoiceField的查询集。如果要将每个ModelChoiceField更改为使用每个外键关系的另一端的对象填充,您将看到表单中的ModelChoiceField现在包括年度,问题和文章。

以下是使用每个字段的正确查询集的示例。

annuals = forms.ModelChoiceField(queryset=Annual.objects.all())
issues = forms.ModelChoiceField(queryset=Issue.objects.all())
articles = forms.ModelChoiceField(queryset=Article.objects.all())

重要的是要从文档中注意到,ModelChoiceField只允许在给定表单中选择每个查询集中的单个对象。如果您希望允许用户从每个查询集中选择多个对象,那么您可能希望改为使用ModelMultipleChoiceField

此外,您可以从文档中注意,在查询集中每个对象的选项字段中显示的默认值将是主键。如果要在选择选择窗口小部件的选项中为每个对象显示不同的字段值,则应使用ModelChoiceField的第二个可选参数to_field_name。这是指模型中将显示在选择选择器中的字段。

相关问题