Первичный ключ и уникальный ключ в django

#django #primary-key #unique-key

#django #первичный ключ #уникальный ключ

Вопрос:

У меня был пользовательский первичный ключ, который необходимо настроить для определенных данных в модели.

Этого было недостаточно, так как попытка вставить дубликат номера увенчалась успехом. Так что теперь, когда я заменяю primary_key=True на unique=True , он работает должным образом и отклоняет повторяющиеся номера !!. Но согласно этому документу (который использует поля).

primary_key=True подразумевает null=False и unique=True.

Что приводит меня в замешательство , например , почему он принимает значение в первую очередь при наличии встроенного unique=True ?

Спасибо.

Обновленное заявление:

    personName = models.CharField(primary_key=True,max_length=20)
  

Ответ №1:

Вместо этого используйте AutoField with primary_key .

Редактировать:

Если вы не используете AutoField , вам придется вручную вычислить / установить значение для поля первичного ключа. Это довольно громоздко. Есть ли причина, по которой вам нужен ReportNumber первичный ключ? У вас все еще может быть уникальный номер отчета, по которому вы можете запрашивать отчеты, а также автоматически увеличивающийся целочисленный первичный ключ.

Правка 2:

Когда вы говорите, что допускаются повторяющиеся значения первичного ключа, вы указываете, что происходит обновление существующей записи с одним и тем же первичным ключом — на самом деле в базе данных нет двух объектов с одним и тем же первичным ключом (чего не может быть). Проблема заключается в том, как уровень ORM Django выбирает выполнение UPDATE (изменение существующей записи БД) по сравнению с INSERT INTO (создание новой записи БД). Ознакомьтесь с этой строкой из django.db.models.base.Model.save_base() :

 if (force_update or (not force_insert and
        manager.using(using).filter(pk=pk_val).exists())):
    # It does already exist, so do an UPDATE.
  

В частности, этот фрагмент кода:

 manager.using(using).filter(pk=pk_val).exists()
  

Здесь говорится: «Если запись с таким же первичным ключом, как эта Model , существует в базе данных, то выполните обновление». Поэтому, если вы повторно используете первичный ключ, Django предполагает, что вы выполняете обновление, и, таким образом, не вызывает исключения или ошибки.


Я думаю, лучшая идея — позволить Django сгенерировать для вас первичный ключ, а затем создать отдельное поле ( CharField или что-то еще) с unique ограничением.

Комментарии:

1. @mipadi : Мои требования касаются того, чтобы установить его вручную. Я понимаю ваше беспокойство по поводу AutoFiled . Но опять же, ваше решение решило бы запрос там, где я хочу, чтобы это было автоматическое поле. Для этого мне нужен был ручной ввод от регистратора. Опять же, даже если я использую CharFiled , я бы заменил исходное поле новой CharField записью. И если вы обратили внимание на последнюю часть моего вопроса, я задал вопрос о том, почему это не сработало? Почему он заменяет , даже если у него есть значение по умолчанию unique=True в primary_key ?

2. @Нагарадж Тантри: Верно. Я спрашиваю, почему именно номер отчета должен быть первичным ключом. У вас может быть уникальный, введенный вручную номер отчета (вы даже можете проиндексировать его, чтобы ускорить запросы), а также отдельный, автоматически сгенерированный идентификационный номер (который также является первичным ключом).

3. Кроме того, какой сервер базы данных вы используете?

4. @mipadi: Мне, конечно, пришлось сохранить номер записи, поскольку администратор хотел, чтобы он был с целым числом. Я использую Sqlite3 . Поскольку у меня есть еще одна похожая проблема с personName=models.CharField(primary_key=True,max_length=20) , я подумал опубликовать вопрос только с одним полем, а не с двумя похожими запросами.

5. И кроме того, на сам вопрос я не получаю никакого ответа, поэтому я снова обновлю вопрос с помощью CharField . Это даже проблема с CharField .