简体   繁体   English

Django - Model 管理器问题 - 查询

[英]Django - Problem with Model Manager - Query

I'm still a beginner and I'm stuck in a challenging spot for me.我仍然是一个初学者,我被困在一个对我来说具有挑战性的地方。 I can't get data from a foreign key table to be inserted "correctly" into a column of a ListView.我无法从外键表中获取数据以“正确”插入到 ListView 的列中。

I basically want to create a list view of a table (FeatureFilm).我基本上想创建一个表的列表视图 (FeatureFilm)。 This also works.这也有效。 But in one column I get information from another table and here I get data, but not the one that belongs to the particular table row.但是在一列中,我从另一个表中获取信息,在这里我获取数据,但不是属于特定表行的数据。

Here are my models.这是我的模型。 The table I want to show is "FeatureFilm" model. This model is inherited from my base Project class "ProjectBaseModel".我要显示的表是“FeatureFilm”model。这个 model 继承自我的基础项目 class“ProjectBaseModel”。 Then there is another table "CompanyInvolved Model".然后是另一个表“CompanyInvolved Model”。 This is attached to the FeatureFilm table with a foreign key (feature_id).它附加到带有外键 (feature_id) 的 FeatureFilm 表。

So movies are stored (FeatureFilm) and different companies are involved in the creation process of the movies.所以电影被存储(FeatureFilm)并且不同的公司参与了电影的创作过程。 (CompanyInvolved) (涉及公司)

class ProjectBaseModel(models.Model):
    title = models.CharField("Titel", max_length=100, blank=False, unique=True)

    leading_postproduction_id = models.ForeignKey(
        Company,
        verbose_name="Federführende Postproduktion",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )
    phase = models.CharField(choices=post_phase, max_length=30, blank=True, null=True)
    former_title = models.CharField("Titel, ehemalig", max_length=100, blank=True)
    title_international = models.CharField(
        "Titel, international", max_length=100, blank=True, null=True, unique=True
    )

class FeatureFilm(ProjectBaseModel):
    class Meta:
        verbose_name = "Kinofilm"
        verbose_name_plural = "Kinofilme"
        ordering = ["title"]

class ProductionManager(models.Manager):
    def get_production(self):
        return (
            super()
            .get_queryset()
            .filter(company_role="Produktion", is_production_list=True)
            .values_list("company_involved__name")
        )


class CompanyInvolved(models.Model):
    feature_id = models.ForeignKey(
        FeatureFilm,
        on_delete=models.CASCADE,
        null=True,
        blank=True,
    )
    tv_movie_id = models.ForeignKey(
        TvMovie, on_delete=models.CASCADE, null=True, blank=True
    )
    company_role = models.CharField(
        choices=company_role,
        max_length=15,
        blank=True,
        help_text="Produktion, Co-Produktion, Kinoverleiher, Sender, Weltvertrieb",
    )
    company_involved = models.ForeignKey(
        Company,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
    )


    is_production_list = models.BooleanField(
        default=False,
        verbose_name="Produktion in Liste",
    )
    productionmanager = ProductionManager()

    def __str__(self):
        return "#" + str(self.pk)

    class Meta:
        verbose_name = "Produktion, Co-Produktion, Verleih, Sender, Weltvertrieb"
        verbose_name_plural = "Produktion, Co-Produktion, Verleih, Sender, Weltvertrieb"
        ordering = ["pk"]

I basically wanted to generate the output now via the template.我现在基本上想通过模板生成 output。 I can iterate the lines with the template for loop.我可以使用循环模板迭代这些行。 But I also learned that more complex queries don't work in the DjangoTemplate language, or simply don't belong there.但我还了解到,更复杂的查询在 DjangoTemplate 语言中不起作用,或者根本不属于那里。 I don't need every row of data from the CompanyInvolved, but only the company_role = "Production" and is_production_list = True.我不需要 CompanyInvolved 的每一行数据,只需要 company_role = "Production" 和 is_production_list = True。 A combined "Where" clause in the template now nice, but doesn't exist, so I built myself a MODEL MANAGER (ProductionManager) that does this filtering in the model.模板中的组合“Where”子句现在很好,但不存在,所以我自己构建了一个 MODEL MANAGER (ProductionManager),它在 model 中执行此过滤。

here is the View:这是视图:

class FeatureListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
    permission_required = "project.can_access_featurefilm_list"
    model = FeatureFilm
    template_name = "project/feature-list.html"

    def handle_no_permission(self):
        return redirect("access-denied")

ans here is the depending snippet in the template: ans 这里是模板中的依赖片段:

              <tbody>

                {% for project in object_list %}
                    <tr>

                        <td><a href="{% url 'feature-detail-date' project.pk %}">{{ project.title }}</a></td>

                        <td>{{ project.companyinvolved_set.get_production }}
                        <br>
                        </td>
                        <td>{% if project.program_length_planned %}
                                {{ project.program_length_planned }}
                            {% endif %}
                        </td>
                        <td>{{ project.global_shooting_resolution }}</td>
                        <td>{{ project.global_resolution_theatrical }}</td>
                        <td>{% if project.hdr == 1%}
                                ja
                            {% else %}
                                nein
                            {% endif %}

                        </td>
                        <td>{{ project.stafflist.postproduction_supervisor_id.username }}</td>
                        <td>{% if project.phase %}
                            {{ project.phase }}
                            {% endif %}

                        </td>


                    </tr>

                  {% endfor %}
              </tbody>

so I iterate over each movie project with {% for project in object_list %} and then I want to show in my "problem" column the company that has the role production and since there can be more than one, the one that was previously marked by the user for the lists view - > is_production_list = TRue and then the output should come: {{ project.companyinvolved_set.get_production }}.所以我用 {% for project in object_list %} 遍历每个电影项目,然后我想在我的“问题”列中显示具有角色制作的公司,因为可以有多个,之前标记的那个由列表视图的用户 - > is_production_list = TRue 然后 output 应该来:{{ project.companyinvolved_set.get_production }}。

The result is going in the right direction, but it is still not finally correct.结果是朝着正确的方向前进,但仍然没有最终正确。 I get the CompanyINvolved data and these are also filtered by company_role = "Production" and is_production_list = True, but these values are now displayed to me each time in each individual Row the same, I get so not per ROW the associated productions but simply each time ALL.我得到了 CompanyINvolved 数据,这些数据也由 company_role = "Production" 和 is_production_list = True 过滤,但是这些值现在每次在每个单独的行中都显示给我,所以我得到的不是每行相关的制作,而是每个时间全部。 I'm missing the reference to the FeatureFilm object, but I don't know how to get this now, or where to put this reference now?我缺少对 FeatureFilm object 的引用,但我现在不知道如何获取它,或者现在将此引用放在哪里?

changed my template:更改了我的模板:

 <tbody>

                {% for project in object_list %}
                    <tr>

                        <td><a href="{% url 'feature-detail-date' project.pk %}">{{ project.title }}</a></td>

                        <td>
                          !! {{ project.production_companies.company_involved.name}}!!
                            <br>
                        </td>
                        <td>{% if project.program_length_planned %}
                                {{ project.program_length_planned }}
                            {% endif %}
                        </td>
                        <td>{{ project.global_shooting_resolution }}</td>
                        <td>{{ project.global_resolution_theatrical }}</td>
                        <td>{% if project.hdr == 1%}
                                ja
                            {% else %}
                                nein
                            {% endif %}

                        </td>
                        <td>{{ project.stafflist.postproduction_supervisor_id.username }}</td>
                        <td>{% if project.phase %}
                            {{ project.phase }}
                            {% endif %}

                        </td>


                    </tr>

                  {% endfor %}
          </tbody>

I think your code is not working because get_production calls super().get_queryset() , which returns a new QuerySet , without any filters applied, not based on the Queryset in the reverse look up in companyinvolved_set我认为您的代码不起作用,因为get_production调用super().get_queryset() ,它返回一个新的QuerySet ,没有应用任何过滤器,而不是基于在 companyinvolved_set 中反向查找的companyinvolved_set

Your best bet is to add a @property annotation to access the filtered list through your FeatureFilm model最好的办法是添加 @property 注释以通过 FeatureFilm model 访问过滤后的列表

@property
def production_companies(self):
        return [company for company in self.companyinvolved_set.all() if company.company_role == 'Produktion' and company.is_production_list]

Then add this to your template:然后将其添加到您的模板中:

<td>{% for production in project.production_companies %}{{production.company_involved.name}}{% endfor %}</td>

And to prevent a lot of queries, change the get_queryset method in your view to this:为了防止大量查询,请将视图中的 get_queryset 方法更改为:

def get_queryset(self):
    queryset = FeatureFilm.objects.prefetch_related('companyinvolved_set').all()
    return queryset

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM