J'affiche les données de ma base de données MySQL. Je souhaite supprimer les zéros non significatifs dans certains champs (les champs ops et obp ), uniquement lorsque la valeur à gauche du la virgule décimale est un 0. Si le (s) chiffre (s) à gauche de la virgule décimale n'est pas 0, alors je veux évidemment que cela soit affiché.
0,750 devient 0,750
1.000 reste tel quel
Je soupçonne que cela peut être fait lors de l'appel des données à l'aide du modèle django ou dans le fichier views.py. Comment ferais-je l'un ou l'autre?
Toute aide à ce sujet serait grandement appréciée! Merci.
views.py
{% extends "base.html" %}
{% block contents %}
<div>
<table>
<thead>
<tr>
<th>OBP</th>
<th>OPS</th>
<th>TB</th>
</tr>
</thead>
<tbody>
{% for index in battingregstd2018%}
<td>{{ index.obp}}</td>
<td>{{ index.ops}}</td>
<td>{{ index.tb}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
models.py
XXX
HTML
class BattingRegStd(models.Model):
id = models.IntegerField(db_column='ID', primary_key=True) # Field name made lowercase.
obp = models.FloatField(db_column='OBP', blank=True, null=True) # Field name made lowercase.
ops = models.FloatField(db_column='OPS', blank=True, null=True) # Field name made lowercase.
tb = models.IntegerField(db_column='TB', blank=True, null=True) # Field name made lowercase.
3 Réponses :
Exemples que vous pouvez confirmer dans un shell Python, testé avec Python 3.5.3:
x = "0.750"
x.lstrip("0")
> '.750'
# Included because a normal floating point type won't print trailing zeroes:
from decimal import Decimal
x = Decimal("0.750")
x.to_eng_string().lstrip("0")
> '.750'
str(x).lstrip("0")
> '.750'
Bien que vous ne puissiez pas faire cela dans les modèles Django à moins d'avoir échangé le moteur pour jinja2 ou autre chose qui autorise les parens dans les appels de méthode, vous pouvez le faire soit dans la vue (peut-être moche selon la façon dont vous extrayez ces données) ou dans un simple filtre de modèle personnalisé .
Vous pouvez utiliser
def batting_avg_format(num):
numstr = str(num)
if numstr[0]!='0':
return numstr
else:
return numstr[1:]
Soit l'incorporer comme méthode sur votre modèle BattingRegStd et l'appliquer, soit faire directement une compréhension de liste après avoir filtré le modèle mais avant de rendre votre HTML. L'avantage de l'incorporer comme méthode de modèle est que vous pouvez maintenant l'appeler à partir du modèle, tant que le seul paramètre de votre méthode est self.
si vous l'ajoutez à votre modèle, vous le feriez légèrement différemment car ce serait une méthode membre. pour ods, vous feriez quelque chose comme def batting_avg_format (self): numstr = str (self.obs) c'est-à-dire que num serait remplacé par l'attribut que vous voulez formater.
De cette façon, il n'aurait pas besoin de paramètres, et vous pourriez maintenant faire {{someobj.batting_avg_format}} à partir de votre modèle, où someobj est le nom de votre BattingRegStd objet, par exemple index dans votre code.
Quelqu'un peut-il consulter mon code pour voir ce que je fais de mal avec l'approche de Juan? Cliquez sur ce lien pour accéder à mon code: codeshare.io/aybOWo
Je suppose que la valeur est supérieure à zéro.
views.py
{% for index in battingregstd2018%}
<td>
{% if index.obp is None %}
-
{% elif index.obp < 1 %}
.{{index.obp|slugify|slice:"1:"}}
{% else %}
{{index.obp}}
{% endif %}
</td>
{% endfor %}
que deuxième tentative,
corrigeons simplement le modèle cette fois. utilisez la vue d'origine.py
def batting(request):
battingregstd2018 = BattingRegStd.objects.filter(year=2018)
for i in range(0, len(battingregstd2018)):
# if need to edit value
if battingregstd2018[i].obp is not None and battingregstd2018[i].obp < 1:
# data edit as string
# data type does not matter in template
battingregstd2018[i].obp = str(battingregstd2018[i].obp)[1:]
if battingregstd2018[i].ops is not None and battingregstd2018[i].ops < 1:
battingregstd2018[i].ops = str(battingregstd2018[i].ops)[1:]
return render(request, 'playerstats/battingReg2018.html', {'battingregstd2018':battingregstd2018})
. {{index.obp | slugify | slice: "1:"}}
| slice ne peut être utilisé que dans le type de données chaîne.
| slugify se convertit en ASCII pour une utilisation | slice . mais la virgule décimale est supprimée.
j'ai donc ajouté . à l'avant.
ps)
peut-être que le type float stockera 0.750 comme 0.75 . si vous voulez 0.750 que de l'utiliser .{{index.obp|floatformat:"3"|slugify|slice:"1:"}}
son affichage '<' non pris en charge entre les instances de 'NoneType' et 'int' ... Aussi, comment aurais-je appelé des opérations dans mes modèles?
@NickT si cela fonctionnait bien avant (0.750, 1.000, ...), pas besoin de modifier le modèle. je n'ai pas vu que la valeur était vide. J'ai ajouté une condition dans l'instruction if.
Dommage. Ne fonctionne toujours pas. Il affichera le modèle sans l'erreur maintenant, mais aucun changement. Affiche toujours le 0 avant les points décimaux. Étais-je littéralement censé copier et coller ceci dans les vues, changer le urls.py pour qu'il pointe vers la vue batting et appeler le modèle comme ? {{index.ops | default_if_none: "-" | floatformat: 3}}
@NickT j'essaye une autre manière.
prédire ... que le second fonctionne et c'est le plus simple! Apparemment, peu de gens le savent. J'ai demandé sur quelques forums. Beaucoup de vues, seulement quelques réponses et une solution! La seule chose que j'ajouterais est le | floatformat: "3" dans l'instruction else