Cómo usar correctamente la búsqueda FK inversa de Django para mostrar instancias del modelo hijo en CBV
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 UpdateView
como 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 UpdateView
como 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
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_related
antes get
corrige el error de 'Group' object has no attribute 'prefetch_related'
.
Además, puede dejar de usar prefetch_related
y solo hacer get
desde la consulta anterior y también funcionará, pero prefetch_related
se sugiere usar para optimizar el rendimiento, ya que obtendrá las empresas relacionadas cada vez.
Luego, en su template
, puede simplemente llamar related_grp_company.all
desde el objeto, digamos que está pasando el Group
objeto actual group
a su plantilla, por lo que debería ser group.related_grp_company.all
, esta es una QuerySet
lista, 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 all
que estábamos llegando <app>.Company.None
antes
Propina:
related_name
se usa para la relación inversa , sugeriría cambiarle el nombre a companies
para 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()