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

#django #django-models

#django #django-модели

Вопрос:

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

 # model.py
class Invoice(models.Model):
    # IntegrityError "Column 'expireDays' cannot be null"
    expireDays = models.PositiveSmallIntegerField(default=1)

    # expireDays = *null* in DB
    expireDays = models.PositiveSmallIntegerField(default=1, blank=True, null=True)

# forms.py
class InvoiceForm(forms.ModelForm):
    # leaving this line out gives invalid form
    expireDays = forms.IntegerField(required=False)
    class Meta:
        model = Invoice
  

(Я использовал только одну строку объявления поля за раз. 🙂

Я даже не уверен, что я правильно объявляю значение по умолчанию. Единственная ссылка, которую я смог найти на это, была в статье о вариантах обработки Джеймса Беннетта. Мне еще предстоит найти его в документах Django (я использую версию 1.2 — может быть, это в 1.3?)

Обновление — Я попытался установить значение поля по умолчанию в базе данных MySQL, но безрезультатно. Кажется, что даже когда у формы нет значения для поля, она продолжает и присваивает БД null, превышая значение по умолчанию MySQL.

Хотя в настоящее время я просто устанавливаю значение по умолчанию в представлении, которое создает форму — мне это не очень нравится, поскольку это возлагает ответственность за целостность поля на представление, а не на базу данных.

То, как я думал, что это сработает, заключается в том, что поле может быть установлено или нет в форме — если установлено, это значение будет записано в БД, а если не установлено, будет использоваться значение по умолчанию в БД. Вместо этого, если не задано, форма записывает null в базу данных. Так какой смысл иметь значение по умолчанию в объявлении ModelField, если оно не используется? Что именно это делает?

Ответ №1:

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

 class Invoice(models.Model):
    expireDays = models.PositiveSmallIntegerField(default=1, blank=True, null=True)

class InvoiceForm(forms.ModelForm):
    class Meta:
        model = Invoice
  

обновление, поэтому, если значение не установлено, используйте 1 в качестве значения поля:

 class InvoiceForm(forms.ModelForm):

    def clean_expireDays(self):
        exp_days = self.cleaned_data.get('expireDays')
        if exp_days is None:
            return self.fields['expireDays'].initial
            # above can be: return 1
            # but now it takes value from model definition
        else:
            return exp_days

    class Meta:
        model = Invoice
  

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

1. Возможно, мое сообщение было непонятным, но это одна из комбинаций, которые я пробовал — и поле данных MySQL отображается как null , когда я это делаю, а не как 1 .

2. Прокомментируйте обновление — на самом деле, я делаю это другим способом — устанавливаю для поля в (скопированных) данных POST значение по умолчанию 1, прежде чем передавать данные POST в форму. Но это все же помещает логику для поддержания целостности данных внутри формы, а не в базу данных, где я этого хочу. База данных MySQL должна присваивать значение по умолчанию. Чего я ожидал бы, так это того, что если форма не получит значения, она не будет пытаться установить значение DB — но, похоже, она присваивает DB значение NULL, которое переопределяет даже значение по умолчанию, которое я установил вручную в DB.