Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

183
Visualizações
Django: recupera un solo objeto de la relación ManyToMany de manera efectiva

Tengo una estructura de base de datos que se puede simplificar de la siguiente manera (la versión y la información adicional no se muestran porque no están directamente relacionadas con mi pregunta):

 class Image(models.Model): file = models.ImageField(blank=False, null=False, upload_to='images') version = models.ForeignKey(Version, blank=False, null=False) class ExampleImage(models.Model): example = models.ForeignKey('Example', blank=False, null=False) image = models.ForeignKey(Image, blank=False, null=False) additional_info = models.ForeignKey(AdditionalInfo, blank=True, null=True) class Example(models.Model): name = models.Charfield(max_length=255) images = models.ManyToManyField(Image, through=ExampleImage, through_fields=('example', 'image') def get_default_image(self): try: image = self.images.get(version=Version.objects.get(name=DEFAULT_VERSION)) except Image.DoesNotExist: # Get some other image, this happens maybe 1 out of 10

Ahora tengo una necesidad muy común de consultar todos los objetos de ejemplo junto con su imagen predeterminada. Actualmente, estoy haciendo algo como lo siguiente:

 example_list = [] examples = Example.objects.all() for example in examples: example_dict = dict(name=example.name, image=example.get_default_image()) example_list.append(example_dict) # Then show example_list in template

Este enfoque funciona, pero genera miles de consultas a la base de datos y tarda más de un minuto en ejecutarse, ¡lo cual es demasiado tiempo para descargar una sola página web!

Entonces mi pregunta es, ¿cuál es el enfoque correcto para optimizar este tipo de caso de uso? Posiblemente podría configurar el campo default_image para el modelo de ejemplo (y usar select_related entonces, pero esto hace que agregar imágenes sea más complicado), codificar la identificación de la versión para el método get_default_image (no tan flexible), hacer el método get_default_image para cached_property, etc. pero estoy no estoy exactamente seguro de qué enfoque se debe utilizar. Ya probé muchos trucos pero nada parece ayudar a mi situación. Debería encontrar una solución que me permita consultar tanto el ejemplo como la imagen predeterminada con una gran consulta, en lugar de hacer el trabajo en bucle for.

about 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

¿ DEFAULT_VERSION es una constante de módulo? Si es así, puede factorizar la llamada version=Version.objects.get(name=DEFAULT_VERSION) para que no tenga que ejecutarla para cada example in examples .

También debería poder trabajar con un objeto Prefetch personalizado: https://docs.djangoproject.com/en/1.11/ref/models/querysets/#django.db.models.Prefetch . Algo parecido a esto (aunque tendrás que probarlo y modificarlo tú mismo):

 qs = Image.filter(version=Version.objects.get(name=DEFAULT_VERSION)) pref = Prefetch('images', queryset=qs, to_attr='image') examples = Example.objects.prefetch_related(pref)

Idealmente, por supuesto, establecería Example.default_image en OneToOneField para que pueda recuperar las imágenes predeterminadas de manera eficiente.

El decorador cached_property realmente no lo ayudará aquí, porque solo almacena en caché la propiedad mientras exista la instancia. Ayuda si necesita llamar a instance.get_default_image() varias veces, pero aún deberá ejecutar get_default_image una vez para cada instancia que obtenga.

Espero que ayude

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda