В приложении Django мне нужно создать номер заказа, который выглядит следующим образом: yyyymmddnnnn, в котором yyyy = год, mm = месяц, dd = день, а nnnn - это число от 1 до 9999.
Я думалЯ мог бы использовать последовательность PostgreSQL, поскольку сгенерированные числа являются атомарными, поэтому я могу быть уверен, что когда процесс получит число, уникальное число.
Итак, я создал последовательность PostgreSQL:
CREATE SEQUENCE order_number_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9999
START 1
CACHE 1
CYCLE;
Эта последовательность может быть доступна как таблицы, имеющие одну строку.Поэтому в файле checkout.py я создал модель Django для доступа к этой последовательности.
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'
Я установил имя sequence_name в качестве первичного ключа, поскольку Django настаивает на наличии первичного ключа в таблице.
Я создал файл get_order_number.py с содержимым:
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
теперь, когда я вызываю get_new_order_number () из интерактивной оболочки django, он ведет себя как положено.
>>> 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'
Вы видите числа, постепенно увеличивающиеся на единицу каждый раз, когда вызывается функция.Вы можете запустить несколько интерактивных сессий django, и номера будут постепенно увеличиваться, при этом в разных сессиях не будет идентичных номеров.
Теперь я пытаюсь использовать вызов этой функции из вида:
import get_order_number
order_number = get_order_number.get_new_order_number()
и это дает мне номер.Однако в следующий раз, когда я получаю доступ к представлению, оно увеличивает число на 2. Я понятия не имею, в чем проблема.