Django: сделать пользовательский ПК с автоинкрементом? - PullRequest
6 голосов
/ 06 января 2011

Я использовал пользовательские первичные ключи для модели в Django.(Это было потому, что я импортировал значения в базу данных, и к ним уже были прикреплены идентификаторы, и имело смысл сохранить существующие значения.)

class Transaction(models.Model):
    id = models.IntegerField(primary_key=True)
    transaction_type = models.IntegerField(choices=TRANSACTION_TYPES)
    date_added = models.DateTimeField(auto_now_add=True)

Однако теперь я хочу добавить новые экземпляры модели.в базу данных, и я хотел бы автоматически создать уникальный первичный ключ.Но если я не укажу идентификатор во время создания экземпляра, я получу сообщение об ошибке:

t = Transaction(transaction_type=0)
t.save()

дает:

IntegrityError at /page
(1048, "Column 'id' cannot be null")

Как автоматически сгенерировать уникальный идентификатор дляуказать для новых значений, без необходимости изменять способ импорта существующих значений?

ОБНОВЛЕНИЕ

Я написал этот пользовательский метод, который, кажется, работает ...

class Transaction(models.Model):
    def save(self, *args, **kwargs):
        if not self.id:
            i = Transaction.objects.all().order_by('-id')[0]
            self.id = i.id+1
        super(Transaction, self).save(*args, **kwargs) 

Ответы [ 4 ]

3 голосов
/ 15 августа 2012

Вы можете использовать AutoField для столбца id вместо IntegerField. Следующее должно работать для вас:

id = models.AutoField(primary_key=True)

id теперь будет увеличиваться автоматически и не будет иметь проблем с параллелизмом, поскольку это может возникнуть в методе save.

3 голосов
/ 22 августа 2012

В итоге я использовал очень похожий фрагмент кода, но сделал его немного более общим:

def save(self, *args, **kwargs):
    if self.id is None:
        self.id =  self.__class__.objects.all().order_by("-id")[0].id + 1
    super(self.__class__, self).save(*args, **kwargs)

он использует self.__class__, поэтому вы можете просто скопировать этот код в любой класс модели, ничего не меняя.

2 голосов
/ 06 января 2011

Как вы импортируете существующие значения? Было бы несложно записать что-то в ваш Transaction s __init__, чтобы сгенерировать для вас новый идентификатор, но, не зная, как вы импортируете другие значения, я не могу точно сказать, изменит ли это способ вашей работы. с ними.

0 голосов
/ 09 декабря 2014

Если вы удалите объявленное поле идентификатора, django автоматически примет это:

id = models.AutoField(primary_key=True)

В Django 1.8 inspectdb автоматически обнаружит auto_increment и будет использовать AutoField при создании моделей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...