【问题标题】:Django DetailView queryset returns an empty listDjango DetailView 查询集返回一个空列表
【发布时间】:2021-01-19 02:50:26
【问题描述】:

DetailView 查询集返回我怀疑来自模型的__str__ 方法的全名。

型号:

class Profile(models.Model):
  user = models.OneToOneField(User, on_delete=models.CASCADE)
  ...

class Employee(models.Model):
  user = models.ForeignKey(User, on_delete=models.CASCADE)
  ...

注意:用户 == 员工模型中的个人资料 pk 查看:

class EmpDetail(DetailView):
    template_name = 'users/emp_detail.html'
    model = Employee
    context_object_name = 'employee'

我试过这个,它得到了我需要的东西,但是 id 是硬编码的,我无法访问 kwargs:

def get_object(self, queryset=None):
        employee = Employee.objects.filter(user=self.request.user, id="1").values('full_name', 'val2', 'val3', ... ) 
        return employee

然后我尝试了这个,但它返回一个空列表。

def get_context_data(self, **kwargs):
        context = super(EmpDetail, self).get_context_data(**kwargs)
        pk_= self.kwargs.get("id")
        context['employee'] = Employee.objects.filter(pk=pk_).values('full_name', 'val2', 'val3', ... ) 
        return context

如何在 DetailView 中进行查询并将其传递给模板?

【问题讨论】:

  • 你有,在self.kwargs。

标签: django django-templates django-queryset


【解决方案1】:

我试过了,它得到了我需要的东西,但是 id 是硬编码的,我无权访问kwargs。

您可以使用self.kwargs 访问URL kwargs,例如:

def get_object(self, queryset=None):
    return Employee.objects.get(
        user=self.request.user,
        pk=self.kwargs['id']
    )

请不要使用.values(…) [Django-doc]。这将侵蚀逻辑模型层。你应该只在某些用例中使用.values(…),例如当你想GROUP BY某个字段时。如果列数很大,你仍然可以使用.only(…) [Django-doc]来限制带宽。

对于DetailView,你不需要自己过滤id,你可以让Django帮你做。您可以通过覆盖.get_queryset(…) method [Django-doc] 来限制用户拥有的项目:

class EmpDetail(DetailView):
    template_name = 'users/emp_detail.html'
    model = Employee
    context_object_name = 'employee'
    pk_url_kwarg = 'id'

    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).filter(
            user=self.request.user
        )

通过指定pk_url_kwarg [Django-doc],你可以让Django自己过滤主键。

您可以通过以下方式获取附加到用户的个人资料:

{{ user<b>.profile</b> }}

因此,如果Profile 有一个名为ImageField 的ImageField,例如,您可以通过以下方式获取媒体网址:

&lt;img src="{{ user<b>.profile.image.url</b> }}"&gt;

当然,您需要将 Django 配置为 serve media files during development [Django-doc]。在生产环境中,您需要配置网络服务器(如 Apache 或 Nginx)来提供媒体文件。

【讨论】:

  • 我得到“TypeError at /1/ 'Employee' object is not iterable”
  • @KuyatehYankz:因为这是一个单个对象,你不能{% for ... in employee %},employee是一个Employee,所以在你的模板中,你只需渲染这个比如{{ employee.full_name }}。
  • 这太优雅了,如何查询视图中的第二个模型?
  • @KuyatehYankz:通常DetailView 用于显示一个对象的详细信息。您究竟要显示什么对象?它与Employee 对象有什么关系?
  • 我想从 Profile 模型中列出雇主名称、地址和徽标
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 2018-12-01
  • 2021-06-06
  • 2015-10-08
  • 2018-08-06
  • 1970-01-01
相关资源
最近更新 更多