Django – modal 창에 form error 출력
Django model forms (https://github.com/trco/django-bootstrap-modal-forms/blob/master/README.rst) 이용하고 있는데, 모달 창이 뜬 상태에서 form submit 을 수행하고, 에러가 발생하면 해당 모달창에 바로 띄워주고 싶어서 시도!
원래 제공되는 기능인데, 그냥 쓴 방법을 정리해 둔다.
모달창 템플릿 코드는 아래와 유사하게 되어 있다. 여기서 div class=”invalid” 부분이 중요하다. 여기서 class invalid 부분을 빼 버리면, 모달창에 표시되는게 아니라 전체 페이지가 모달 창을 띄우는 페이지로 바뀌어 버려 브라우저 전체에 모달창 템플릿만 표기되는 문제가 있다.
<div class="modal-body">
<div class="invalid mb-2">
</div>
</div>
설명이 어려워서 그림으로 남겨둔다.
이렇게 표기되기를 원하는데, 빨간색 표기는 <p> 태그에 의해서 표기되는 것이라 div class invalid 를 빼고 실행했더니, 쩝 모달창이 사라지고 전체페이지를 잡아 먹는 모양새가 되버리네. class css 에 먼가가 정리되어 있나 보다.
일단 그럼 에러를 띄워주는 부분의 코드는 아래를 참고
class ShippingProductUpdateForm(BSModalModelForm):
title = ""
# update_firmware_version = forms.CharField(label=_("업데이트버전"), widget=forms.TextInput(attrs={"readonly": True}))
class Meta:
model = ShippingProduct
# fields = ["product", "serial", "status", "version", "update_firmware_version", "date_shipping", "shipping_company"]
fields = ["product", "serial", "status", "date_shipping", "shipping_company"]
labels = {
"shipping_company": _("출고회사"),
"product": _("*상품"),
"serial": _("*시리얼"),
"status": _("*상태"),
"date_shipping": _("*출고일"),
}
widgets = {
"shipping_company": forms.Select(attrs={"class": ""}),
"product": forms.Select(attrs={"class": "", "placeholder": "상품"}),
"serial": forms.TextInput(attrs={"class": ""}),
"status": forms.Select(attrs={"class": ""}),
"date_shipping": forms.DateInput(attrs={"type": "date", "required": True}),
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
print("ShippingProductUpdateForm init", self.request.user.profile.level, self.request.user.profile.company)
self.title = "출고상품 수정"
self.fields["product"].queryset = Product.objects.filter(company_id=self.request.user.profile.company, is_deleted=0)
# if self.instance.update_firmware:
# self.fields["update_firmware_version"].initial = self.instance.update_firmware.version
# else:
# self.fields["update_firmware_version"].initial = "No update"
if self.request.user.is_superuser:
self.fields["product"].label_from_instance = lambda obj: "%s (%s)" % (obj.name, obj.company.name)
def clean(self):
cd = self.cleaned_data
print("ShippingProductUpdateForm", cd)
# 에러발생 시키기 예제
raise ValidationError(
_("첨부파일을 입력하세요: %(value)s"),
code="invalid",
params={"value": cd.get("product")},
)
# return cd
- clean 부분에 강제로 에러를 띄워 줬더니 잘 동작하는 것을 확인했다.
그리고, form submit 할 때 Validation check 를 미리 하지 않고 view, form function 에서 걸러내고 싶다면, 템플릿에서 아래와 같은 키워드를 submit 부분에 추가해 준다. formnovalidate="formnovalidate"
<button id="update" type="submit" formnovalidate="formnovalidate" >