Django: хотите пройти через _set только для значений pk - PullRequest
0 голосов
/ 07 октября 2019

Я застрял, пытаясь выяснить, как фильтровать значения моего шаблона в подробном представлении PK. У меня есть подробный вид для моего сотрудника. Я хочу отобразить предметы моего сотрудника, где я затем хочу отфильтровать предметы с оценками, которые были сделаны для предмета.

Я дошел до того, что могу показать названия своих предметов и показать всеоценки для каждого предмета. Однако я не хочу показывать ВСЕХ из них, я только хочу показать те, которые существуют для текущего сотрудника (detailView PK). Как вы можете видеть в моем шаблоне, я использую _set для создания отношения, но я понятия не имею, как отфильтровать PK в это уравнение.

Пример, что я хочу:

Тема 1:

Оценочное имя - сотрудник Джонни

Оценочное имя - сотрудник Джонни

Пример того, что у меня сейчас есть:

Тема 1:

Оценочное имя - сотрудник Джонни

Оценочное имя - сотрудник Крис

Я не хочу оценки Криса, я только хочу отфильтровать первичный ключ, поэтому в этом случае оценки Джонни.

Шаблон

{% for subject in subject_list %}
    <a href="">{{ subject.subejctname }}</a>
    {% for evaluation in subject.evaluation_set.all %}
        <div>
        <p>{{ evaluering.ma }} | {{ evaluering.ma.firstname }} | {{ evaluering.ma.lastname }}</p>
        </div>
    {% empty %}
        <p>No evaluations founds.</p>
    {% endfor %}
{% endfor %}

Просмотр

class EmployeeDetailView(DetailView):
    template_name = 'evalsys/employee/alle_employees_eval.html'
    model = Employee

    # Uses employee PK to make a detail view
    def view_employee_with_pk(self, pk=None):
        if pk:
            employee = Employee.objects.get(pk=pk)
        else:
            employee = self.employee
        args = {'employee': employee, }
        return render(self, 'evalsys/employee/alle_employees_eval.html', args)

    def get_context_data(self, **kwargs):
        context = super(EmployeeDetailViewDetailView, self).get_context_data(**kwargs)
        context['subject_list'] = Subject.objects.all()
        return context

Модель объекта

class Subject(models.Model):
   id = models.AutoField(primary_key=True)
   subjectname = models.CharField(max_length=255, help_text="Indtast navnet på faget.")
   slug = models.SlugField(max_length=200, unique=True)

Оценочная модель

class Evaluation(models.Model):
   id = models.AutoField(primary_key=True)
   employee_num = models.ForeignKey('Employee', on_delete=models.CASCADE, null=True)
   subjectname = models.ForeignKey('Subject', on_delete=models.CASCADE, null=True)

Модель сотрудника

class Employee(models.Model):
   id = models.AutoField(primary_key=True)
   slug = models.SlugField(max_length=200)
   employee_num = models.IntegerField(help_text="Indtast medarbejderens MA-nummer. (F.eks 123456)")
   firstname = models.CharField(max_length=30, help_text="Indtast medarbejderens fornavn.")
   lastname = models.CharField(max_length=30, help_text="Indtast medarbejderens efternavn.")
   subjectname = models.ForeignKey('Subject', on_delete=models.CASCADE, null=True)

Ответы [ 2 ]

0 голосов
/ 07 октября 2019

Обратные отношения (subject.evaluation_set) могут быть предварительно выбранными , это метод для уменьшения количества запросов к базе данных, выполняемых при обращении к обратным отношениям для многих объектов в наборе запросов. При использовании следующего набора запросов при доступе к subject.evaluation_set.all он не будет выполнять дополнительный доступ к БД, поскольку результат уже был кэширован в каждом экземпляре

Subject.objects.all().prefetch_related('evaluation_set')

Этот кэшированный результат можно изменить с помощью Предварительная выборка объектов. Используя их, вы можете ограничить содержимое subject.evaluation_set.all только тем результатом, который вы хотите

Subject.objects.all().prefetch_related(
    Prefetch(
        'evaluation_set',
        queryset=Evaluation.objects.filter(employee=self.employee)
    )
)
0 голосов
/ 07 октября 2019

Структура вашей модели сбивает с толку. Вы в состоянии детализировать отношения между сотрудником, предметом и оценкой ?? Вы упомянули, что хотите отобразить темы сотрудника, но с помощью структуры вашей модели сотрудник может иметь только один объект, поскольку сотрудник связан с объектом внешним ключом.

Ниже я предложил некоторые изменения вназвания вашей модели и ее структуру модели, так что было бы больше смысла получать ваши оценки в шаблоне. Не стесняйтесь задавать вопросы о дизайне вашей модели, поскольку это имеет решающее значение для разработки ваших представлений, шаблонов и т. Д.

Также см. Здесь соглашения об именах моделей
Справочник по внешнему ключу Django
Стиль кодирования модели Django (PEP8)

Модель объекта

class Subject(models.Model):
   id = models.AutoField(primary_key=True)
   subject_name = models.CharField(max_length=255, help_text="Indtast navnet på 
    faget.")
   slug = models.SlugField(max_length=200, unique=True)

Модель сотрудника

class Employee(models.Model):
    id = models.AutoField(primary_key=True)
    slug = models.SlugField(max_length=200)
    employee_num = models.IntegerField(help_text="Indtast medarbejderens MA-nummer. (F.eks 123456)")
    first_name = models.CharField(max_length=30, help_text="Indtast medarbejderens fornavn.")
    last_name = models.CharField(max_length=30, help_text="Indtast medarbejderens efternavn.")
    subjects = models.ManyToManyField(Subject, related_name='employee', through='Evaluation')

Модель оценки

class Evaluation(models.Model):
   name = models.CharField(blank=True,max_length=50)
   employee = models.ForeignKey('Employee', on_delete=models.CASCADE)
   subject = models.ForeignKey('Subject', on_delete=models.CASCADE)

Таким образом, предполагается, что сотрудник может иметь разные предметы, а отображение определяется через сквозную модель с использованием многих ко многим.

Ваш DetaiView может быть просто

class EmployeeDetailView(DetailView):
    template_name = 'evalsys/employee/alle_employees_eval.html'
    model = Employee

    def get_context_data(self, **kwargs):
        context = super(EmployeeDetailViewDetailView, 
          self).get_context_data(**kwargs)
        context['evaluations'] = Evaluation.objects.filter(employee=self.object)
        return context

Шаблон

{% for evaluation in evaluations %}
    <a href="">{{ evaluation.subject.subject_name }}</a>
    <p>{{ evaluation.name }} | {{ evaluation.employee.first_name }} |
       {{evaluation.employee.last_name }}</p>
{% empty %}
    <p>No evaluations founds.</p>
{% endfor %}
...