重定向和'字段'从数据库中检索对象时的关键字问题

时间:2017-12-08 07:46:06

标签: django django-views django-queryset django-class-based-views

我有3种型号的帐户,公司和产品。

公司可以有多个产品,账户可以有多个公司。

class Product(Meta):
    company = models.ForeignKey(Company, related_name='products', on_delete=models.CASCADE)

class Company(Meta):
    account = models.ForeignKey(Account, related_name='account', on_delete=models.CASCADE)

我正在使用Django 2.0新的网址模式,我定义了网址:

 path('dashboard/', include('accounts.urls',  namespace='accounts')),
帐号urls.py

中的

 path('companies/<int:pk>/', AccountCompanyDetailView.as_view(), name='detail_company'),

在我试图获取产品实例的CBV中,如果产品不存在,请检查公司是否不存在,并根据上述结果进行重定向。

我覆盖def get_object(self)

class AccountCProduct(DetailView):
 model = Product
    template_name_suffix = '_account_detail'

    def get_object(self):

        company_pk = self.kwargs.get('pk1')
        product_pk = self.kwargs.get('pk2')

        account = self.request.user.account
        if not account:
            raise Http404
        try:
            product = Product.objects.get(company__account=account, company__pk=company_pk, pk=product_pk)
        except Product.DoesNotExist:
            try:
                company = Company.objects.get(account=account, pk=company_pk)
                print(company)
            except Company.DoesNotExist:
                return redirect('accounts')
            print('redirect 1')
            return redirect('accounts:detail_company', pk=company_pk)

        return product

如果我在上面使用它(公司代码已注释),当产品出错时没有错误,但重定向不会发生。

如果我取消评论公司部分,我会收到字段错误:

Cannot resolve keyword 'company' into field. 

company是公司模型的产品型号上的ForeignKey。

我在公司查询之后,而不是之前,如果没有必要,产品查找不要进行两次查找。

我想要实现的目标,例如:

帐户有2个公司有ID 1和2,公司1有产品ID为1

http://127.0.0.1:8000/dashboard/companies/1/products/1/

将转到公司1的产品

http://127.0.0.1:8000/dashboard/companies/1/products/2/

将失败,因为公司1没有ID为2的产品并重定向到公司1详细信息页面

http://127.0.0.1:8000/dashboard/companies/3/products/2/

会失败,因为首先找不到该产品,然后在帐户中找不到ID为3的公司并返回帐户信息中心

1 个答案:

答案 0 :(得分:1)

您无法从get_object()方法内部进行重定向。该方法必须返回一个模型对象 - 您无法从那里返回响应。

您需要在get()方法中执行此逻辑。我认为最简单的方法是更换整个方法:

def get(self, request, *args, **kwargs):
    company_pk = kwargs.get('pk1')
    product_pk = kwargs.get('pk2')

    account = request.user.account
    if not account:
        raise Http404()
    try:
        self.object = Product.objects.get(company__account=account, company__pk=company_pk, pk=product_pk)
    except Product.DoesNotExist:
        try:
            company = Company.objects.get(account=account, pk=company_pk)
        except Company.DoesNotExist:
            return redirect('accounts')

        return redirect('accounts:detail_company', pk=company_pk)

    context = self.get_context_data(object=self.object)
    return self.render_to_response(context)

请注意,您在此处直接设置了self.object,并且根本不再使用get_object()