Django DetailView queryset returns 一个空列表

Django DetailView queryset returns an empty list

全名上的 DetailView 查询集 returns,我怀疑它来自模型的 __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)
  ...

注意:用户 == Employee 模型中的 Profile 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

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

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 中进行查询并将其传递给模板?

I tried this and it gets me what I need but the id is hard coded in, I don't have access to kwargs.

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

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

不要使用.values(…) [Django-doc]. This will erode the logical model layer. You should only use .values(…) in certain use cases, for example when you want to GROUP BY a certain field. If the number of columns is large, you can still use .only(…)</strong> [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'
    <b>pk_url_kwarg = 'id'</b>

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

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

您可以通过以下方式获取附加到用户的配置文件:

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

因此,如果 Profile 有一个名为 imageImageField,您可以通过以下方式获取媒体 url:

<img src="{{ user<b>.profile.image.url</b> }}">

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