从数据库检索对象时出现重定向和 'field' 键盘问题

Redirect and 'field' keyword issues when retriving objects from database

我有 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 新的 url 模式,并且我定义了 urls:

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

在帐户中 urls.py

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

在 CBV 中,我正在尝试获取 Product 实例,如果 Product 不存在,请检查 Company 是否不存在,并根据上述结果进行重定向。

我覆盖了 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 是产品模型到公司模型的外键。

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

我想实现的,例子:

帐户有 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 的公司,returns 到帐户仪表板

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

您需要在 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()