خطای ValidationError در جنگو
خطای ValidationError در جنگو زمانی رخ میدهد که دادههای ورودی شما با قوانین تعریفشده برای اعتبارسنجی دادهها سازگار نباشند. این خطا میتواند در بخشهای مختلف جنگو، از جمله فرمها، مدلها و سریالایزرها رخ دهد.
دلایل رایج بروز خطای ValidationError
-
ورودی نامعتبر در فرمها:
دادههای فرم معمولاً اعتبارسنجی میشوند. اگر دادههای فرم از قوانین اعتبارسنجی تعریف شده در کلاس مربوطه عبور نکنند، یک خطای اعتبارسنجی رخ میدهد. البته اگر دادههایی که در فرمها ارسال مینمایید با فیلدهای تعریفشده در فرم مطابقت نداشته باشند، نیز جنگو این خطا را به شما نشان خواهد داد.
در ادامه نحوه استفاده از فرمهای جنگو برای بررسی دادههای ورودی در قالب یک مثال به طور کامل شرح داده شده است.
در مثال تصویر 1 با استفاده از کلاس forms.Form یک فرم به نام MyForm و یک فیلد متنی (name) تعریف شده که حداکثر طول مجاز آن ۱۰ کاراکتر است (max_length=10) و دادهای که وارد فرم شده، یک متن فارسی با طول بیش از ۱۰ کاراکتر است.
.webp)
تصویر(1)
همانطور که مشخص است؛ متد ()is_valid روی فرم اجرا شده و بررسی میکند که آیا دادههای ورودی با قوانین فرم مطابقت دارند یا خیر.
به دلیل اینکه طول متن بیش از حد مجاز است، فرم نامعتبر شناخته شده و خطا در قالب یک دیکشنری در form.errors ذخیره میشود.
-
محدودیتهای فیلد مدل:
هنگامی که یک مدل جنگو تعریف میکنید، میتوانید محدودیتها و قوانین اعتبارسنجی مختلفی را برای فیلدهای آن با استفاده از گزینههای موجود مانند max_length، unique، null، blank و روشهای اعتبارسنجی سفارشی مشخص کنید. اگر دادهها با این محدودیتها مطابقت نداشته باشند، هنگام تلاش برای ذخیره نمونه مدل، یک خطای اعتبارسنجی ممکن است رخ دهد.
مثلاً اگر فیلد مدل CharField طولی محدود داشته باشد و برای (max_length=10) تعریف گردد؛ چنانچه دادهای طولانیتر از 10 کاراکتر وارد کنید با خطای ValidationError مواجه خواهید شد.
در ادامه نحوه استفاده از محدودیتهای اعتبارسنجی روی فیلدهای مدل و همچنین استفاده از متد ()full_clean برای بررسی دادههای یک شیء مدل در قالب مثالی مجزا بررسی شده است.
در مثال تصویر 2 مدل MyModel یک فیلد به نام name داشته و این فیلد از نوع CharField بوده که طول آن با استفاده از ویژگی max_length=10 به حداکثر ۱۰ کاراکتر محدود شده است.
شیء obj از مدل MyModel ساخته و اجرای اعتبارسنجی با : ()full_clean انجام شده است.
متد ()full_clean روی شیء فراخوانی میشود و همه اعتبارسنجیهای مرتبط با مدل، شامل محدودیتهای فیلدها و اعتبارسنجهای سفارشی را اجرا میکند.
.webp)
تصویر(2)
به دلیل اینکه طول متن بیش از حد مجاز است، عدم اعتبار تأیید شده و خطا در قالب یک دیکشنری در message_dict ذخیره میشود.
-
اعتبارسنجی سفارشی:
اگر اعتبارسنجی سفارشی تعریف کرده باشید و دادههای وارد شده نتوانند این اعتبارسنجی را پشت سر بگذارند، با ValidationError مواجه خواهید شد.
به عنوان مثال در کد تصویر 3 تابعی به نام validate_even تعریف شده که زوج بودن یک عدد را بررسی میکند و اگر عدد وارد شده فرد باشد؛ ValidationError رخ داده خواهد شد.
شیوه کار به این صورت است که:
-
یک تابع تعریف شده که مقدار ورودی (value) را بررسی میکند.
-
اگر مقدار ورودی شرط ایجاد شده را نداشته باشد (در اینجا عدد زوج نباشد)، یک استثنا از نوع ValidationError ایجاد میشود.
-
این تابع به عنوان یک اعتبارسنج (validator) به فیلد مدل اضافه شده است.
.webp)
تصویر(3)
-
اعتبارسنجی در سریالایزرها
در Django REST Framework (DRF)، سریالایزرها مسئول تبدیل دادهها به فرمت JSON (یا سایر فرمتهای قابل انتقال) و اعتبارسنجی ورودیها هستند. میتوان محدودیتهای اعتبارسنجی استاندارد و سفارشی را روی سریالایزرها اعمال کرد.
در ادامه مثالی بررسی شده که یک سریالایزر برای مدل تعریف شده و اعتبار دادهها را بررسی میکند.
در این مثال مدل بهصورت تصویر 4 نوشته شده است.
.webp)
تصویر(4)
برای سریالایزر نیز کد تصویر 5 درج گردیده است:
.webp)
تصویر(5)
از validate_price برای اعتبارسنجی یک فیلد خاص (در اینجا price) استفاده شده و اگر مقدار price کمتر یا مساوی صفر باشد، یک خطای اعتبارسنجی برمیگرداند.
متد validate برای اعتبارسنجی دادههای شیء استفاده میشود؛ در این مثال بررسی می گردد که مقدار stock نمیتواند منفی باشد.
متد is_valid دادهها را بررسی میکند. اگر دادهها نامعتبر باشند، خطاهای اعتبارسنجی در خاصیت errors سریالایزر ذخیره میشوند.