Набор запросов Django DetailView возвращает пустой список

#django #django-templates #django-queryset

#django #django-шаблоны #django-queryset

Вопрос:

DetailView queryset возвращает полное имя, которое, как я подозреваю, исходит из метода модели __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 в модели Employee
Вид:

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

Я попробовал это, и это дает мне то, что мне нужно, но идентификатор жестко запрограммирован, у меня нет доступа к 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 и передать его в template?

Комментарии:

1. У вас есть, он находится внутри self.kwargs .

Ответ №1:

Я попробовал это, и это дает мне то, что мне нужно, но идентификатор жестко запрограммирован, к которому у меня нет доступа kwargs .

Вы можете получить доступ к kwargs URL с self.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] для ограничения пропускной способности.

Для a DetailView вам не нужно фильтровать id самостоятельно, вы можете позволить Django сделать это за вас. Вы можете ограничить элементы, принадлежащие пользователю, переопределив .get_queryset(…) метод [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.profile }}  

Поэтому, если Profile у ImageField него есть имя image , например, вы можете получить URL-адрес носителя с помощью:

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

конечно, вам нужно будет настроить Django для обслуживания медиафайлов во время разработки [Django-doc]. В рабочей среде вам нужно будет настроить веб-сервер (например, Apache или Nginx) для обслуживания медиафайлов.

Комментарии:

1. Я получаю «Ошибка типа в / 1/ Объект ‘Employee’ не может быть повторен»

2. @KuyatehYankz: поскольку это один объект, вы не можете {% for ... in employee %} , employee это an Employee , поэтому в вашем шаблоне вы просто визуализируете это, например {{ employee.full_name }} .

3. Это так элегантно, как я могу запросить вторую модель в представлении?

4. @KuyatehYankz: обычно a DetailView предназначен для отображения сведений об одном объекте. Какой именно объект вы хотите отобразить? Как это связано с Employee объектом?

5. Я хочу перечислить имя, адрес и логотип работодателей из модели профиля