Django在ModelForm中使用特定模型

时间:2016-12-05 03:16:02

标签: django django-models

class Report(models.Model):  
    # ....
    product = models.ForeignKey(Product)


class Product(models.Model):
    name = models.CharField(max_length=50)


class Item(models.Model):
    box = models.ForeignKey(BoxInTransport)
    product = models.ForeignKey(Product)


class BoxInTransport(models.Model):
    transport = models.ForeignKey(Transport)
    box = models.ForeignKey(Box)

这是 - 简而言之 - 模型的结构。

我有一个视图可以让我创建新的报告:

class ReportCreateView(CreateView):
    model = Report
    form_class = ReportForm

    def get_form_kwargs(self):
        # updating to get argument from url
        kwargs = super(DifferenceCreateView, self).get_form_kwargs()
        kwargs.update(self.kwargs)
        return kwargs

和表格:

class ReportForm(ModelForm):
    class Meta:
        model = Report
        fields = [
            'product'
        ]

    def __init__(self, box_nr=None, *args, **kwargs):
        super(ReportForm, self).__init__(*args, **kwargs)

        self.fields['product'].queryset = ???

如何才能获得属于特定盒子的这些产品?更清楚:

只有产品:

Item.objects.filter(box__box__box_code=box_nr)

现在我得到了我需要的所有项目,但我需要将self.fields ['products']传递给只有这个新项目查询集的产品表单。

你能帮助我吗?

修改

我尝试过这样的事情:

 def __init__(self, box_nr=None, *args, **kwargs):
    super(ReportForm, self).__init__(*args, **kwargs)
    queryset = Item.objects.filter(
        box__box__box_code=boxno
    )
    none_queryset = Product.objects.none()
    list_or_products = [p.product for p in queryset]
    product_queryset = list(chain(none_queryset, list_or_products))
    self.fields['product'].queryset = product_queryset

但是,首先 - 它看起来有点难看:),第二 - 它不起作用:

AttributeError: 'list' object has no attribute 'all'

1 个答案:

答案 0 :(得分:1)

您的__init__看起来像这样:

def __init__(self, box_nr=None, *args, **kwargs):
    super(ReportForm, self).__init__(*args, **kwargs)

    qs = Product.objects.filter(item__box__box__box_code=box_nr)
    self.fields['product'].queryset = qs

基本上,您需要在ProductItem上进行反向查找。您可以阅读relevant documentation here

请注意:item__box__box__box_code=box_nr基于我对您的模型的理解。 item__box执行反向查找。休息可能需要根据您的模型定义进行一些调整。