Dans mon modèle
Django, j'ai défini une @property
qui a bien fonctionné et la propriété peut être affichée dans le list_display
de l'administrateur sans aucun problème.
J'ai besoin de cette propriété non seulement dans l'administration mais aussi dans ma logique de code à d'autres endroits également, il est donc logique de l'avoir comme propriété pour mon modèle.
Maintenant, je voulais rendre la colonne de cette propriété triable, et avec l'aide de la documentation de Django sur l'objet When, cette question StackOverflow pour le calcul de F() et ce lien pour le tri, j'ai réussi à construire la solution fonctionnelle ci-dessous.
La raison pour laquelle je pose une question ici est : en fait, j'ai implémenté ma logique deux fois, une fois en python et une fois sous forme d'expression, ce qui va à l'encontre de la règle de conception consistant à implémenter la même logique une seule fois. Je voulais donc demander si j'ai raté une meilleure solution à mon problème. Toute idée est appréciée.
Voici le modèle (identifiants modifiés) :
class De(models.Model):
fr = models.BooleanField("[...]")
de = models.SmallIntegerField("[...]")
gd = models.SmallIntegerField("[...]")
na = models.SmallIntegerField("[...]")
# [plusieurs_attributs, Meta, __str__() supprimés pour plus de lisibilité]
@property
def s_d(self):
if self.fr:
return self.de
else:
return self.gd + self.na
Voici l'administration du modèle :
class DeAdmin(admin.ModelAdmin):
list_display = ("[...]", "s_d", "gd", "na", "de", "fr" )
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(
_s_d=Case(
When(fr=True, then='s_d'),
When(fr=False, then=F('gd') + F('na')),
default=Value(0),
output_field=IntegerField(),
)
)
return queryset
def s_d(self, obj):
return obj._s_d
s_d.admin_order_field = '_s_d'
Si vous n'avez pas d'autre moyen, j'apprécierais également une confirmation du fait en tant que réponse.