Почему я могу сохранить экземпляр модели django без определения всех ненулевых полей - PullRequest
0 голосов
/ 04 июня 2019

Когда я определяю ненулевое поле в django, это позволяет мне сохранить экземпляр модели без указания какого-либо значения для этого ненулевого поля. Это не то, что я ожидал. Как я могу заставить это привести к ошибке?

Postgres 9.1 Джанго 2.1 окна питон 3,6

from django.db import models
class Wwtp(models.Model):
    name = models.CharField(max_length=100, null=False,
                            blank=False, unique=True)
    short_name = models.CharField(
        max_length=10, null=False, blank=False, unique=True)

Как и ожидалось, мне не разрешено сохранять его с явным пустым коротким именем.

mdl.Wwtp.objects.create(name='Wwtp4', short_name=None)

Но мне разрешено сохранять экземпляр Wwtp без указания короткого имени:

mdl.Wwtp.objects.create(name='Wwtp4')

и когда я пытаюсь:

mdl.Wwtp.objects.create()

это дает мне

django.db.utils.IntegrityError: duplicate key value violates unique constraint "api_wwtp_short_name_key"
DETAIL:  Key (short_name)=() already exists.

Очевидно, что django заполнил базу данных пустым значением для short_name, хотя это нельзя делать ... Как я могу заставить базу данных запретить это?

1 Ответ

1 голос
/ 04 июня 2019

Вы не можете с CharField.Пустое значение - это пустая строка '', а не NULL.У вас уже есть набор blank=False, поэтому, если вы очистите свою модель или модели, сохраните их, вы поймете это.Но это не может быть применено на уровне базы данных.

Обратите внимание, что blank=False, null=False является значением по умолчанию, поэтому вам не нужно указывать это.

Кроме того, если вы действительно хотите толькоПоддерживая PostgreSQL, вы можете выполнить пользовательскую миграцию, используя RunSQL, чтобы создать столбец в таблице, вручную добавив SQL, необходимый для добавления ограничения (например, используя CHECK).См. здесь , чтобы узнать, как Django также знает, что столбец был создан, и не пытается добавить его при следующей миграции.Здесь есть пример .

[Редактировать] В Django 2.2 вы можете добавить CheckConstraint в атрибут Meta модели constraints атрибута:

from django.db.models import CheckConstraint, Q

    (...)
    class Meta:
        constraints = [
            CheckConstraint(
                check=~Q(name=''), 
                name='name_not_empty'),
            CheckConstraint(
                check=~Q(short_name=''),
                name='short_name_not_empty']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...