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

197
Visualizações
Hacer que Django ORM obtenga propiedades automáticamente

Digamos que tengo un modelo de publicación como este:

 class Post(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) text_content = models.CharField() @property def comment_count(self): return self.comments.count()

Digamos que necesito obtener todos los datos para la publicación con ID 3. Sé que puedo recuperar al usuario junto con la publicación en una consulta, haciendo Post.objects.select_related('user').get(pk=3) , permitiéndome guardar una consulta. Sin embargo, ¿hay alguna manera de obtener automáticamente comment_count también?

Sé que podría usar Post.objects.annotate(comment_count=Count('comments')) (que requerirá que elimine la propiedad o cambie el nombre de la anotación, ya que habría un AttributeError ), sin embargo, ¿es posible hacer que el ORM haga esa parte automáticamente, ya que la propiedad está declarada en el modelo?

Aunque podría simplemente agregar el .annotate , esto puede volverse muy tedioso cuando hay varias propiedades y claves externas que deben buscarse en varios lugares.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Tal vez esta no sea una solución perfecta para usted, pero puede encontrar algo similar que funcione. Puede agregar un administrador de objetos personalizado, consulte los documentos

Entonces podría agregar un método como with_comment_count() . O si siempre desea anotar, puede modificar el conjunto de consultas inicial .

 class PostManager(models.Manager): def with_comment_count(self): return self.annotate( comment_count=Count('comments') ) # Or this to always annotate def get_queryset(self): return super().get_queryset().annotate( comment_count=Count('comments') ) class Post(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) text_content = models.CharField() objects = PostManager()

Entonces podrías consultar así.

 post = Post.objects.get(pk=1).with_comment_count() post.comment_count
over 4 years ago · Santiago Trujillo Relatório

0

¡Gracias a Felix Eklöf logré hacerlo funcionar! Como se especifica en la pregunta, esto fue en el caso en el que había varias propiedades/claves externas que necesitaban captación previa y, como tal, se necesitaba la capacidad de "encadenar" la captación previa. Esto no es posible encadenando métodos de PostManager , ya que no devuelven un PostManager sino un QuerySet , sin embargo, se me ocurrió una función que almacena en caché todo lo que se le pide que almacene en caché de una vez, evitando la necesidad de encadenar métodos:

 class PostManager(models.Manager): def caching(self, *args): query = self.all() if 'views' in args: query = query.annotate(view_count=Count('views')) if 'comments' in args: query = query.annotate(comment_count=Count('comments')) if 'user' in args: query = query.select_related('user') if 'archives' in args: query = query.prefetch_related('archives') return query class Post(models.Model): objects = PostManager() ... # caching can then be added by doing, this, for instance: Post.objects.caching('views', 'user', 'archives').get(id=3)

Tenga en cuenta que para que esto funcione, también tuve que cambiar @property a @cached_property , lo que permitió que el ORM reemplazara el valor y permitiera el almacenamiento en caché adecuado con el mismo nombre.

over 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