#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
.