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>

설명이 어려워서 그림으로 남겨둔다.

![](assets/images/2023/02/3_image-1.png?ssl=1)

이렇게 표기되기를 원하는데, 빨간색 표기는 <p> 태그에 의해서 표기되는 것이라 div class invalid 를 빼고 실행했더니, 쩝 모달창이 사라지고 전체페이지를 잡아 먹는 모양새가 되버리네. class css 에 먼가가 정리되어 있나 보다.

![](assets/images/2023/02/image-2.png?ssl=1)

일단 그럼 에러를 띄워주는 부분의 코드는 아래를 참고

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" >      

참고 사이트

Share: Twitter Facebook
Bongjun Hur's Picture

About Bongjun Hur

BJ is a dev.

Seoul, Korea https://devbj.com