اذهب إلى المحتوى
  • 0

تقييد القيم المسموح بها في نموذج Model في جانغو Django

Amer Abdallah

السؤال

لدى جانغو Django العديد من الحقول الرقمية المتاحة للاستخدام في النماذج models. فهل هناك أي طريقة لتقييد حقل معين لتخزين الأرقام فقط ضمن نطاق معين ، على سبيل المثال يمكن للحقل تخزين الأرقام من 0.0 إلى  5.0 فقط؟

كيف يمكن عمل ذلك على حقل من نوع IntegerField في جانغو Django؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 1

يوفر جانغو المعامل validators في الحقل IntegerField حيث يقبل هذا المعامل قائمة من المتحققات (دوال مبنية في جانغو Django يمكنها التحقق من قيمة الحقل قبل تخزينها)، وبالتالي يمكنك إضافة شروط على كل حقل مثل تحديد أقصى قيمة يمكن تخزينها وأدنى قيمة أيضًا، ويمكنك عمل ذلك على النحو التالي:

from django.db.models import IntegerField, Model
from django.core.validators import MaxValueValidator, MinValueValidator

class UserModel(Model):
    age = IntegerField(
        default=18,
        validators=[
            MaxValueValidator(100),
            MinValueValidator(18)
        ]
     )

بعد عمل التعديل السابق على الحقل، يجب أن يتم إستدعاء التابع full_clean من النموذج حتى يتمكن جانغو Django من التعرف على هذه التغيرات، مع العلم أن هذا الإستدعاء غير ضروري للنماذج من نوع ModelForm.

يوجد أيضًا طريقة أخرى وهي عمل حقل مخصص وتقوم بعد ذلك بكتابة أكواد التحقق validating بنفسك، كما في المثال التالي:

from django.db import models

class IntegerRangedField(models.IntegerField):
    def __init__(self, verbose_name=None, name=None, min_value=None, max_value=None, **kwargs):
        self.min, self.max = min_value, max_value
        models.IntegerField.__init__(self, verbose_name, name, **kwargs)
        
    def formfield(self, **kwargs):
        defaults = {'min': self.min, 'max':self.max}
        defaults.update(kwargs)
        return super(IntegerRangeField, self).formfield(**defaults)

لاحظ أن الحقل IntegerRangedField الذي قمنا بعمله يقوم بالوراثة من الحقل IntegerField، بعد ذلك يمكنك أن تستخدم هذا الحقل المخصص على النحو التالي:

from django.db.models import Model

class UserModel(Model):
    age = IntegerRangedField(min_value=18, max_value=100)

بالطبع يجب أن تقوم بإستدعاء الصنف IntegerRangedField من المكان الذي أنشأته فيه.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

إليك حل ممتاز في حال كنت تريد بعض المرونة الإضافية ولا تريد تغيير مجال النموذج الخاص بك. عن طريق validator مخصص:

from django.core.exceptions import ValidationError      

class validate_range_or_null(object):
    compare = lambda self, a, b, c: a > c or a < b
    clean = lambda self, x: x
    message = ('Ensure this value is between %(limit_min)s and %(limit_max)s (it is %(show_value)s).')
    code = 'limit_value'
    def __init__(self, limit_min, limit_max):
        self.limit_min = limit_min
        self.limit_max = limit_max
    def __call__(self, value):
        cleaned = self.clean(value)
        params = {'limit_min': self.limit_min, 'limit_max': self.limit_max, 'show_value': cleaned}
        if value:  # اجعله اختياريًا ، أو قم بإزالته لجعله مطلوبًا، أو اجعله مطلوبًا في النموذج 
            if self.compare(cleaned, self.limit_min, self.limit_max):
                raise ValidationError(self.message, code=self.code, params=params)

حيث أن المعلمتان هما max و min ، وتسمح بقيم nulls. كما يمكنك تخصيص validator إذا كنت ترغب في ذلك عن طريق التخلص من عبارة if أو تغيير الحقل ليصبح blank = False، null = False في النموذج. سيتطلب ذلك بالطبع عملية migration.  ويمكن استخدامه على هذا النحو:

class YourModel(models.Model):
    ....
    no_dependents = models.PositiveSmallIntegerField("How many dependants?", blank=True, null=True, default=0, validators=[validate_range_or_null(1,100)])

 

تم التعديل في بواسطة Ali Haidar Ahmad
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

هناك طريقتان للقيام بذلك. الأول هو استخدام التحقق من صحة النموذج لعدم السماح لأي مستخدم بإدخال أي رقم يزيد عن 50, إذا لم يكن هناك مستخدم مشارك في العملية ، أو إذا كنت لا تستخدم نموذجا لإدخال البيانات ، فسيتعين عليك عمل override لدالة model's save لطرح استثناء أو تقييد البيانات التي تدخل الحقل.يمكنك أيضا تجربة الحل التالي

SCORE_CHOICES = zip( range(1,n), range(1,n) )
score = models.IntegerField(choices=SCORE_CHOICES, blank=True)

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...