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