محتويات الدورة

Django / سير تطبيق موثوق / الدرس 8

ModelForms والتحقق من المجال

استخدم حقولا معلنة وتنظيفا صريحا مع إبقاء هوية الخادم والقيود المتزامنة خارج العميل.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • اختيار شكل مدخل العملية
  • اختبار عقد مشترك دون حفظ
  • التحقق من الثابت النهائي بحدود الثقة

اختيار شكل مدخل العملية

يربط ModelForm حقولا بالنموذج ويعيد التحقق المناسب ولا يعني إباحة كل سمة. حدد حقول العملية لا جميعها مع إخفاء المرئي. تنتمي الملكية والإشراف والتدقيق غالبا للخادم. قد تختلف الإنشاء والتعديل والجزئي، ويحتاج حقل التخزين قيدا أضيق. احفظ شكلا قابلا للمراجعة كي لا توسع سمة جديدة الكتابة العامة. ومن مزايا القائمة الصريحة أن إضافة حقل إداري إلى النموذج لاحقا لا تمنح العميل القدرة على كتابته تلقائيا عبر نموذج كان يقبل كل الحقول.

تنظيف الحقول والعلاقات بالمستوى المناسب

تفحص clean_field حقلا بعد تنظيفه وتقارن clean المشتركة قيما وتضيف خطأ عاما أو محددا. استدع الأب ولا تفترض وجود كل مفتاح بعد فشل سابق. تختلف نهاية بعد بداية عن صحة العددين. اجعل الرمز والرسالة قابلين للتصحيح والترجمة دون تفاصيل القاعدة. وإذا فشل تنظيف حقل منفرد فقد لا توجد قيمته في cleaned_data، لذلك يجب أن يعالج الفحص المشترك غيابها بدلا من توليد استثناء جديد.

اختبار عقد مشترك دون حفظ

يتحقق البرنامج من مجال عددي بـget ويقارن بعد نجاح الطرفين. يسبب التساوي خطأ عاما رغم صحة كل عدد. لا يتصل بقاعدة ولا يفرض معنى جدولة ومنطقة للأعداد. افحص موضع الخطأ دون جملة مترجمة حرفية. يحتاج الحقيقي تاريخا ومنطقة وتداخلا وإذنا؛ تعزل العينة ثابتا واحدا قابلا للاشتقاق. ولا تحمل الأعداد المجردة في المثال سياسة مناطق زمنية أو تعارض مواعيد؛ فقد عزلنا ترتيب الطرفين حتى يكون سبب الخطأ ومكانه واضحين.

python مثال تنفيذي معزول
from django.conf import settings
settings.configure(
    SECRET_KEY="synthetic-course-key",
    USE_I18N=False, USE_TZ=True,
    INSTALLED_APPS=[],
    DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}},
    DEFAULT_AUTO_FIELD="django.db.models.AutoField",
    ALLOWED_HOSTS=["testserver"],
)
import django
django.setup()

from django import forms

class IntervalForm(forms.Form):
    start = forms.IntegerField(min_value=0)
    end = forms.IntegerField(min_value=0)
    def clean(self):
        data = super().clean()
        start, end = data.get("start"), data.get("end")
        if start is not None and end is not None and end <= start:
            raise forms.ValidationError("End must be after start.")
        return data

good = IntervalForm({"start": "2", "end": "5"})
bad = IntervalForm({"start": "2", "end": "2"})
print(good.is_valid(), good.cleaned_data["end"])
print(bad.is_valid(), bool(bad.non_field_errors()))
الناتج المتوقع
True 5
False True

الأعداد صحيحة لكن التساوي يخالف الثابت وينتج خطأ عاما.

تعيين حقول الخادم بعد قبول النموذج

يفترض المقطع Course بعنوان ومقاعد ومالك للمستخدم المهيأ. يسمح النموذج بالحقلين فقط ويربط POST ولو فارغة ويستخدم commit=False ثم يعين الحالي ويحفظ. يحتاج المسارات والوسيط والقالب وCSRF والمخطط. لا يختار العميل المالك. تحتاج علاقات متعدد لمتعدد مع commit=False خطوة save_m2m بعد الحفظ، ولا توجد بالعينة. وبعد استخدام commit=False تظل مسؤولية إكمال الحفظ والعلاقات واقعة على التدفق المعلن، ولا يجوز إعلان النجاح إذا اكتمل جزء من العملية فقط.

python مقطع يتطلب سياق التطبيق
from django import forms
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render
from django.views.decorators.http import require_http_methods
from .models import Course

class CourseForm(forms.ModelForm):
    class Meta:
        model = Course
        fields = ["title", "seats"]

@login_required
@require_http_methods(["GET", "POST"])
def create_course(request):
    form = CourseForm(request.POST if request.method == "POST" else None)
    if request.method == "POST" and form.is_valid():
        course = form.save(commit=False)
        course.owner = request.user
        course.save()
        return redirect("course-detail", course_id=course.pk)
    return render(request, "catalog/course_form.html", {"form": form})
الناتج المتوقع
Valid authorized POST in the declared app: save with current user as owner, then redirect.

يتطلب المخطط والمسارات والوسيط والقالب وCSRF ويعين الخادم المالك ولا ينفذ المقطع.

التحقق من الثابت النهائي بحدود الثقة

قد يتغير المخزن بعد قبول المدخل، فتبقى الفردية والسعة والملكية محتاجة قيودا ومعاملة. لا تعتبر التحقق حجزا أو إذنا. اختبر الزائد والفراغ والمشترك والتعديل والمالك المستبعد. اجلب نسخة التعديل بنطاق مأذون قبل الربط. لا تفرض الحقول المخفية والمعطلة حماية الخادم، واحفظ المدخل الآمن ورسالة العمل عند الرفض. ويجب أن يفصل اختبار التعديل بين صحة الحقول وصحة اختيار النسخة، لأن نموذجا صحيحا تماما قد يرتبط بمورد لا يحق للمستدعي تعديله.

الأخطاء الشائعة وإصلاحها

لا تظهر أخطاء POST الفارغة

لماذا يحدث؟
حولها or None لغير مرتبطة.
كيف تصلحه؟
اربط بحسب الطريقة لا الصدقية.
كيف تتجنب تكراره؟
اختبر الفراغ صراحة.

تفشل clean بعد فشل حقل

لماذا يحدث؟
قرأت مفتاحا مفقودا.
كيف تصلحه؟
استخدم get وافحص الوجود.
كيف تتجنب تكراره؟
اختبر فشل الحقل السابق.

يزور المالك عبر النموذج

لماذا يحدث؟
كُشف حقل الخادم.
كيف تصلحه؟
استبعده وعينه من الهوية.
كيف تتجنب تكراره؟
اختبر المالك الزائد.

اختبر فهمك

1. لماذا يتلقى نموذج التعديل نسخة مقيدة مسبقا؟

اعرض الحل المشروح

قد يعدل ربط حقول صحيحة ببحث غير مقيد موردا لغيره. قيد وافرض العملية ثم اربط الحقول؛ فالصحة والإذن ضمانان.

2. أي خطوة قد تلزم مع commit=False وحقول متعدد لمتعدد؟

اعرض الحل المشروح

احفظ النسخة بعد حقول الخادم ثم save_m2m للعلاقات، ونسقها بمعاملة إن لزم نجاحها معا ولا تدع الجزئي اكتمالا.

أهم ما تعلمته

  • حدد حقول الكتابة صراحة.
  • يحتاج الفراغ المرتبط تحققا.
  • لا تحجز النماذج حالة القاعدة.

المراجع الرسمية