Dans une application Django je dois créer un numéro d'ordre qui ressemble à: yyyymmddnnnn où aaaa = année, mm = mois, dd = jour et nnnn est un nombre compris entre 1 et 9999.Django, l'accès à la séquence de PostgreSQL
J'ai pensé que je pourrais utiliser une séquence PostgreSQL puisque les nombres générés sont atomiques, donc je peux être sûr que lorsque le processus aura un nombre ce nombre est unique.
Je créé une séquence PostgreSQL:
CREATE SEQUENCE order_number_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9999
START 1
CACHE 1
CYCLE;
Cette séquence est accessible en tant que tables ayant une ligne. Donc, dans le fichier checkout.py, j'ai créé un modèle Django pour accéder à cette séquence.
class OrderNumberSeq(models.Model):
"""
This class maps to OrderNumberSeq which is a PostgreSQL sequence.
This sequence runs from 1 to 9999 after which it restarts (cycles) at 1.
A sequence is basically a special single row table.
"""
sequence_name = models.CharField(max_length=128, primary_key=True)
last_value = models.IntegerField()
increment_by = models.IntegerField()
max_value = models.IntegerField()
min_value = models.IntegerField()
cache_value = models.IntegerField()
log_cnt = models.IntegerField()
is_cycled = models.BooleanField()
is_called = models.BooleanField()
class Meta:
db_table = u'order_number_seq'
J'ai défini le nom de séquence comme clé primaire car Django insiste pour avoir une clé primaire dans une table.
Le I a créé un get_order_number.py de fichier avec le contenu:
def get_new_order_number():
order_number = OrderNumberSeq.objects.raw("select sequence_name, nextval('order_number_seq') from order_number_seq")[0]
today = datetime.date.today()
year = u'%4s' % today.year
month = u'%02i' % today.month
day = u'%02i' % today.day
new_number = u'%04i' % order_number.nextval
return year+month+day+new_number
maintenant quand je l'appelle 'get_new_order_number()' depuis le shell django il se comporte comme prévu.
>>> checkout.order_number.get_new_order_number()
u'201007310047'
>>> checkout.order_number.get_new_order_number()
u'201007310048'
>>> checkout.order_number.get_new_order_number()
u'201007310049'
Vous voyez les nombres s'incrémenter de manière agréable d'un cran chaque fois que la fonction est appelée. Vous pouvez démarrer plusieurs sessions django interactives et les nombres s'incrémentent sans aucun chiffre identique apparaissant dans les différentes sessions.
Maintenant, j'essaie d'utiliser appeler cette fonction d'une vue comme suit:
import get_order_number
order_number = get_order_number.get_new_order_number()
et il me donne un numéro. Cependant la prochaine fois que j'accède à la vue, il incrémente le nombre par 2. Je n'ai aucune idée où le problème est.
Je pense que nous devons voir plus de votre code de vue. – KillianDS
Fondamentalement, il n'y a pas beaucoup plus dans le code de la vue. Mais j'ai changé d'avis sur la façon de générer des numéros de commande de toute façon. J'avais besoin de générer des numéros de commande uniques pour pouvoir suivre les commandes si nécessaire. Et la façon dont j'ai essayé, a un sérieux inconvénient. Je dois réinitialiser le compteur tous les jours à minuit exactement. De toute façon, vous tous, merci d'avoir répondu. – Henri
Il est apparu que l'erreur était dans une autre partie de l'application, donc le problème est résolu. Quelque part, j'ai lu quelque chose sur la génération de numéros de commande: http://stackoverflow.com/questions/1179439/best-way-to-generate-order-numbers-for-an-online-store et voici quelques conseils très utiles. – Henri