Cómo usar correctamente la búsqueda FK inversa de Django para mostrar instancias del modelo hijo en CBV

Nov 28 2020

Tengo dos modelos, el campo de uno de ellos apunta al otro como se muestra a continuación:

class Group(models.Model):
    group_company_id = models.CharField(primary_key=True, ...)
    
class Company(models.Model):
    company_id = models.CharField(primary_key=True, ...)
    group_company = models.ForeignKey(Group, related_name="related_grp_company", ...)

Estoy intentando conseguir todas las empresas que se han creado para un grupo en particular . Así que estoy tratando de obtener los company_id(y otros) valores en Djnago UpdateViewcomo una lista en la plantilla. Mi CBV es como se muestra:

class GroupCompanyChangeView(UpdateView):
    template_name =  ...
    model = Group
    form_class = ...
    success_url = reverse_lazy('group_list')

    grp_coy_units = Group.objects.prefetch_related('related_grp_company') # I am trying to get the values of `company_id` in the template but nothing is displayed.

¿Podría alguien decirme cómo hacer que esto funcione?

Actualizar

Como se explicó (@Mahmoud Adel), he modificado mi UpdateViewcomo se muestra a continuación:

class GroupCompanyChangeView(UpdateView):
    template_name =  ...
    model = Group
    form_class = ...
    success_url = reverse_lazy('group_list')

    def get_object(self, *args, **kwargs):
        return Group.objects.get(pk=self.kwargs['pk'])

Y luego en la plantilla, estoy haciendo:

{{ group.related_grp_company }}

Con esto estoy obteniendo una salida de <app>.Company.None.

Respuestas

MahmoudAdel Nov 29 2020 at 07:39

ACTUALIZACIÓN: Después de probar en mi entorno local para resolver los problemas informados en los comentarios, esta es la respuesta final

Deberías anular get_object()

def get_object(self, *args, **kwargs):
        try:
            return Group.objects.prefetch_related('related_grp_company').get(pk=self.kwargs['pk'])
        except:
            return None

Tenga en cuenta que el orden importa aquí en la consulta anterior, hacer prefetch_relatedantes getcorrige el error de 'Group' object has no attribute 'prefetch_related'.

Además, puede dejar de usar prefetch_relatedy solo hacer getdesde la consulta anterior y también funcionará, pero prefetch_relatedse sugiere usar para optimizar el rendimiento, ya que obtendrá las empresas relacionadas cada vez.

Luego, en su template, puede simplemente llamar related_grp_company.alldesde el objeto, digamos que está pasando el Groupobjeto actual groupa su plantilla, por lo que debería ser group.related_grp_company.all, esta es una QuerySetlista, así que repítalo o haz lo que quieras.

por ejemplo:

{%for d in object.related_grp_company.all%}
<h1>{{ d.company_id }}</h1>
{% endfor %}

Porque no agregamos allque estábamos llegando <app>.Company.Noneantes

Propina:

related_namese usa para la relación inversa , sugeriría cambiarle el nombre a companiespara que sea más claro, por ejemplo:

group_company = models.ForeignKey(Group, related_name="companies", ...)

así que usarlo más tarde será como group.companies()