В приложении Django Мне нужно создать номер заказа, который выглядит как: yyyymmddnnnn, в котором гггг = год, мм = месяц, дд = день и нннн это число от 1 до 9999.Django, доступ к последовательности PostgreSQL
Я думал, что могу использовать последовательность 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() 'от Джанго интерактивной оболочки он ведет себя, как ожидалось.
>>> 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. Я понятия не имею, где проблема.
Думаю, нам нужно больше узнать из вашего кода. – KillianDS
В основном код кода отсутствует. Но я изменил свое мнение о том, как создавать номера заказов. Мне нужно было создать уникальные номера заказов, чтобы отслеживать заказы, если это необходимо. И то, как я пытался, имеет серьезный недостаток. Я должен сбросить счетчик каждый день ровно в полночь. В любом случае, все вы, ребята, благодарите за ответ. – Henri
Похоже, что ошибка была в другой части приложения, поэтому проблема решена. Где-то я кое-что прочитал о создании номеров заказов: http://stackoverflow.com/questions/1179439/best-way-to-generate-order-numbers-for-an-online-store и вот некоторые очень полезные советы. – Henri