En supposant le scénario suivant sur deux applications séparées où je souhaite compter le nombre d'éléments de publication d'une catégorie spécifique dans mon modèle:
Categories / models.py
<h5>Number of Post elements: {{ category.posts }}</h5>
Posts / models.py
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(verbose_name="Title")
content = models.TextField(verbose_name="Content")
tag = models.CharField(verbose_name="Meta", max_length=70, blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True)
template.html:
from Posts.models import Post
...
class Category(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=20, verbose_name="Title")
...
@property
def posts(self):
return Post.objects.filter(category_id=self.id).count()
malheureusement, cela entraîne toujours l'erreur suivante:
ImportError: impossible d'importer le nom 'Post' depuis partiellement initialisé module 'Posts.models' (probablement en raison d'une importation circulaire)
4 Réponses :
Cela est probablement dû au fait que vous importez des Posts.models dans vos Categories.models et vice-versa . Vous pouvez l'importer dans la propriété elle-même:
# no from Posts.models import Post
# …
class Category(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=20, verbose_name="Title")
# …
@property
def posts(self):
return self.post_set.count() Mais vous n'avez pas besoin d'importer ce modèle. Django crée automatiquement une relation inversée. Si vous ne spécifiez pas le related_name , c'est modelname_set , vous pouvez donc y accéder avec:
# no from Posts.models import Post
# …
class Category(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=20, verbose_name="Title")
# …
@property
def posts(self):
from Posts.models import Post
return Post.objects.filter(category_id=self.id).count()Remarque : les modules Python sont normalement écrits en snake_case , pas en PerlCase , donc il doit être
category, pas.Category
Merci pour cela :) je préfère la première solution car il est toujours possible d'interroger d'autres champs, merci
Vous devriez essayer d'utiliser le nom associé dans votre propriété:
class Category(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=20, verbose_name="Title")
...
@property
def posts(self):
return self.post_set.count()
De plus, pour mémoire, il semble étrange d'avoir Category et Post dans des applications séparées. Ils devraient probablement être dans une seule application blog . Les importations circulaires impliquent généralement que vous avez deux applications trop étroitement couplées. Dans ce cas, il ne devrait s'agir que d'une seule application.
L'indice est dans l'erreur car vous avez effectivement une importation circulaire.
Posts.models.py aura de Categories.models import Category en haut car vous l'utilisez comme une clé étrangère et comme vous utilisez maintenant Post dans la méthode posts de Category, elle aura from Posys.models import Post
Vous devez résoudre ce problème, ce que vous pouvez faire en un de trois façons selon que vous avez d'autres modèles ou méthodes utilisant la classe Post à partir du modèle Catégories.
Si vous le faites, vous pouvez utiliser l'une de ces deux
@property
def posts(self):
return self.post_set.count()
class Category(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=20, verbose_name="Title")
@property
def posts(self):
from Posts.models import Post
return Post.objects.filter(category_id=self.id).count()
Si vous ne le faites pas, et que nous ne pouvons pas dire ce que vous avez publié, vous pouvez simplement utiliser le nom associé `` post_set`` dans la catégorie classe et évitez du tout l'importation. https://docs.djangoproject.com/en/3.0/topics/db/models/#be-careful-with-related-name-and-related-query-name
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(verbose_name="Title")
content = models.TextField(verbose_name="Content")
tag = models.CharField(verbose_name="Meta", max_length=70, blank=True)
category = models.ForeignKey("Category", on_delete=models.CASCADE, null=True)
Cela résoudra également le problème
Pas besoin de cette propriété, vous pouvez accéder aux objets associés en suivant la clé étrangère vers l'arrière. Consultez la documentation
<h5>Number of Post elements: {{ category.post_count }}</h5>
Ou vous pouvez ajouter une propriété mais directement:
@property
def post_count(self):
return self.post_set.count()
Et puis:
<h5>Number of Post elements: {{ category.post_set.count }}</h5>
vous avez
from Posts.models import Postdans votre modèleCatégories?Oui. Merci pour votre indice, je viens de mettre à jour ma question en conséquence