объект создан, даже если поле было обязательным - PullRequest
0 голосов
/ 03 июля 2018
#models.py

class Mymodel(models.Model):
    name = models.CharField(max_length=100,null=False,blank=False)
    email = models.EmailField(max_length=100,null=False,blank=False)
    password = models.CharField(max_length=120,null=False,blank=False)
    email_notification = models.BooleanField()




#views.py

obj=MyModel.objects.create(name="ok",password="dsfdsfdsfdsfsfds",email_notification=1)

, даже если поле электронной почты было обязательным, тогда я также вижу объект, созданный в админ-панели. В чем может быть проблема, почему объект был создан, даже если поле электронной почты было обязательным? Кроме того, если я захожу в админ-панель и открываю этот объект и нажимаю кнопку «Сохранить», то возникает необходимость в электронном письме

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Примечание. Вы не должны указывать в своих полях null = False, blank = False, поскольку это значения, используемые по умолчанию. (см. Django Field __int__ подпись.).

def __init__(self, verbose_name=None, name=None, primary_key=False,
                 max_length=None, unique=False, blank=False, null=False,
                 db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
                 serialize=True, unique_for_date=None, unique_for_month=None,
                 unique_for_year=None, choices=None, help_text='', db_column=None,
                 db_tablespace=None, auto_created=False, validators=(),
                 error_messages=None):

По умолчанию все поля в базе данных создаются с ограничением NOT NULL. Если вы установите null=True для определенного поля, тогда django установит NULL для столбца в вашей БД. Это эквивалент базы данных Python для ключевого слова None.

Пример с null аргументом

Предположим, у меня есть Mymodel в моем my_app, и я установил email в поле null=True.

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(max_length=100, null=True)
    password = models.CharField(max_length=120)
    email_notification = models.BooleanField()

In Shell,

>> from my_app.models import MyModel

>> new = MyModel.objects.create(name="ok",
                                password="dsfdsfdsfdsfsfds",
                                email_notification=1)
>> new.email == None
>> True # As you can see Django sets db value 
        # as NULL and when we query the data it converts back to Python `None` object.

Пример без null аргумент

Предположим, что у меня есть Mymodel в моем my_app. (Помните, null будет False по умолчанию)

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(max_length=100)
    password = models.CharField(max_length=120)
    email_notification = models.BooleanField()

в оболочке,

>> from my_app.models import MyModel
>> new_obj = MyModel.objects.create(name="test",
                                password="test",
                                email_notification=1)
>> new_obj.email == ''
>> True

То есть Django CharField и TextField значения по умолчанию хранятся в БД в виде пустой строки ('') . Другими словами, если вы создаете объект без предоставления значений для CharField (или TextField) под капотом, Django вызывает метод get_default и возвращает '' (только в этом случае). Это значение будет храниться в базе данных.

Ниже приведен исходный код метода get_default.

def get_default(self):
    """Return the default value for this field."""
    return self._get_default()

@cached_property
def _get_default(self):
    if self.has_default():
        if callable(self.default):
            return self.default
        return lambda: self.default

    if not self.empty_strings_allowed or self.null and not connection.features.interprets_empty_strings_as_nulls:
        return return_None
    return str  # return empty string

Позволяет ответить на вопрос,

Почему объект был создан, даже если поле электронной почты было обязательным?

Ответ EmailField является экземпляром CharField Следовательно, по умолчанию значение '' будет использоваться при создании объекта в базе данных. Вот почему вы не получаете django.db.utils.IntegrityError.

>> new_obj = Mymodel.objects.create(name='tes1t', password='test1', email_notification=1)
>>> new_obj.email
''

Также, если я зайду в админ-панель и открою этот объект и нажму "Сохранить", тогда выясняется, что требуется электронная почта

Помните, blank отличается от null. null связан исключительно с базой данных, тогда как blank связан с проверкой. Поэтому, когда вы создаете объект непосредственно в коде Python или сами выполняете необработанный SQL, вы фактически игнорируете всю проверку ввода Django. Но в админке Django проверяет ввод через форму модели. Поскольку в вашем случае blank имеет значение False (пустое значение не допускается), в форме модели будет отображаться Email is required Ошибка.

Вот соответствующая документация Django для аргумента blank.

1102 * Field.blank *

Если True, поле может быть пустым. По умолчанию это False. Заметка что это отличается от нуля. NULL чисто связан с базой данных, тогда как пробел связан с проверкой. Если поле имеет пустое значение = True, форма Проверка позволит ввести пустое значение. Если поле имеет blank = False, поле будет обязательным.

Дополнительные ресурсы

0 голосов
/ 03 июля 2018

Нет проблем с django, вам нужно будет создать правильную проверку формы модели Django , чтобы пустая строка не игнорировалась и возникла ошибка для пустого поля.

...