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

جعل المشتري لايستطيع طلب كمية اقل من الكمية المحددة

Zeina Almakdisi

السؤال

ضمن مشروع دجانغو خاصة بالتجارة الالكترونية 

قمت بجعل الادمن يحدد الحد الأدنى الذي يمكن للمستخدم طلب كميات من المنتج.. 

** جعل المشتري لايستطيع طلب كمية اقل من الكمية المحددة

مثلا من المنتج رقم ١ ممنوع طلب اقل من ١٠ قطع 

 

لكن المشكلة يظهر للمستخدم ان العداد يبدأ مثلا من الرقم ١٠ ويمكن اخيار الرقم الاصغر

كيف يمكنني منعه؟؟ 

 

 

 

3.jpg

1.jpg

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

Recommended Posts

  • 0

يمكن استعمال الطريقة clean ضمن ال model للتحقق من البيانات كما نشاء، طبعاً يوجد طرق أسهل في حال كان المطلوب هو التحقق بناء على قيمة الحقل فقط و ليس بناء على قيمة أكثر من حقل في نفس الوقت.

حسب ما فهمت تريدين التحقق بناء على حقلين، هما رقم المنتج و الكمية المطلوبة، بحيث الحد الأدنى يعتمد على رقم المنتج.

بافتراض أنك تخزنين الحد الأدنى من أجل كل منتج بناء على رقمه، يمكنك استعمال هذه الدالة بشكل مشابه لما يلي (ما يلي مجرد مثال بسيط يجب تعديله حسب ال model الذي لديك):

from django.core.exceptions import ValidationError
from django.db import models

class Product(models.Model):

  def clean(self):
    errors={}
    # نجلب الحد الأصغري من أجل هذا المنتج بناء على رقمه
    product_lower_bound = products_lower_bound_map[self.product_number]
    # نتحقق فيما إذا كانت الكمية المطلوبة أصغر من الحد الأصغري
    if self.count < product_lower_bound:
      errors['min_count']= f'The min count must be greater than {product_lower_bound}.'

      if errors:
        raise ValidationError(errors)

يمكنك الإطلاع أكثر على ما يمكن فعله باستعمال هذه الطريقة من هنا.

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

  • 0

الإجابة التي تم ذكرها من قبل قيس مشكورًا، تحتوي على فكرة جيدة، وهي استخدام دالة clean() الموجودة في ال model الخاص بالمنتج للتحقق من أن الحد الأدنى المحدد للكمية التي يمكن طلبها لهذا المنتج قد تم الالتزام به.

ولكن، هناك تحدي يحدث عند استخدام هذه الطريقة، وهو أن الخطأ لن يتم عرضه على الحقل المرتبط بالكمية، وإنما سيتم عرضه على النموذج بشكل عام.

لذلك، يمكن استخدام مجموعة العناصر الإضافية (widgets) في Django، وتحويل الحقل المرتبط بالكمية إلى نوع IntegerField والتحقق من الحد الأدنى لهذا الحقل في العنصر الإضافي clean() الخاص به.

فيما يلي مثال محدث للطريقة السابقة:

from django import forms
from django.db import models

class Product(models.Model):
    product_number = models.PositiveIntegerField(unique=True)
    min_count = models.PositiveIntegerField()

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = '__all__'

    count = forms.IntegerField(widget=forms.NumberInput(attrs={'min': '0'}))

    def clean_count(self):
        count = self.cleaned_data['count']
        min_count = Product.objects.get(product_number=self.cleaned_data['product_number']).min_count
        if count < min_count:
            raise forms.ValidationError(f'The minimum count for this product is {min_count}.')
        return count

في المثال، يتم استخدام Django form بدلاً من استخدام clean() في ال model، ويتم إنشاء عنصر إضافي (count) لإدخال الكمية، وتحويل الحقل المرتبط بهذا العنصر الإضافي إلى IntegerField.

ثم التحقق من الحد الأدنى للكمية في clean_count()، وعرض الخطأ على الحقل المرتبط بهذا العنصر الإضافي.

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

  • 0
بتاريخ 13 ساعة قال Mustafa Suleiman:

الإجابة التي تم ذكرها من قبل قيس مشكورًا، تحتوي على فكرة جيدة، وهي استخدام دالة clean() الموجودة في ال model الخاص بالمنتج للتحقق من أن الحد الأدنى المحدد للكمية التي يمكن طلبها لهذا المنتج قد تم الالتزام به.

ولكن، هناك تحدي يحدث عند استخدام هذه الطريقة، وهو أن الخطأ لن يتم عرضه على الحقل المرتبط بالكمية، وإنما سيتم عرضه على النموذج بشكل عام.

لذلك، يمكن استخدام مجموعة العناصر الإضافية (widgets) في Django، وتحويل الحقل المرتبط بالكمية إلى نوع IntegerField والتحقق من الحد الأدنى لهذا الحقل في العنصر الإضافي clean() الخاص به.

فيما يلي مثال محدث للطريقة السابقة:

from django import forms
from django.db import models

class Product(models.Model):
    product_number = models.PositiveIntegerField(unique=True)
    min_count = models.PositiveIntegerField()

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = '__all__'

    count = forms.IntegerField(widget=forms.NumberInput(attrs={'min': '0'}))

    def clean_count(self):
        count = self.cleaned_data['count']
        min_count = Product.objects.get(product_number=self.cleaned_data['product_number']).min_count
        if count < min_count:
            raise forms.ValidationError(f'The minimum count for this product is {min_count}.')
        return count

في المثال، يتم استخدام Django form بدلاً من استخدام clean() في ال model، ويتم إنشاء عنصر إضافي (count) لإدخال الكمية، وتحويل الحقل المرتبط بهذا العنصر الإضافي إلى IntegerField.

ثم التحقق من الحد الأدنى للكمية في clean_count()، وعرض الخطأ على الحقل المرتبط بهذا العنصر الإضافي.

شكرا لكم..

قمت بإضافتها ضمن المودل بعدclass Product

كالتالي:

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = '__all__'
    count = forms.IntegerField(widget=forms.NumberInput(attrs={'min': '0'}))

    def clean_count(self):
        count = self.cleaned_data['count']
        firscoun = Product.objects.get(product_name=self.cleaned_data['product_name']).firscoun
        if count < firscoun:
                raise forms.ValidationError(f'The minimum count for this product is {firscoun}.')
        return count

لكن مازال بإمكانه اختيار الرقم الاصغر من المسموح له

ماالمشكلة؟؟

كذلك قمت بمحاولة استبدال product_name ب id 

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

  • 0
بتاريخ 2 ساعة قال Zeina Almakdisi:

شكرا لكم..

قمت بإضافتها ضمن المودل بعدclass Product

كالتالي:

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = '__all__'
    count = forms.IntegerField(widget=forms.NumberInput(attrs={'min': '0'}))

    def clean_count(self):
        count = self.cleaned_data['count']
        firscoun = Product.objects.get(product_name=self.cleaned_data['product_name']).firscoun
        if count < firscoun:
                raise forms.ValidationError(f'The minimum count for this product is {firscoun}.')
        return count

لكن مازال بإمكانه اختيار الرقم الاصغر من المسموح له

ماالمشكلة؟؟

كذلك قمت بمحاولة استبدال product_name ب id 

هل الإضافة كما قلت لك أيضاً لا تنجح؟ أي أن تقومي بالإضافة  ضمن ال model و ليس ضمن ال form.

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

  • 0
بتاريخ 24 دقائق مضت قال Kais Hasan:

هل الإضافة كما قلت لك أيضاً لا تنجح؟ أي أن تقومي بالإضافة  ضمن ال model و ليس ضمن ال form.

مرحبا استاذ قيس..

لا لم تنجح قمت بتطبيقها على الشكل التالي:

class Product(models.Model):
....
    firscoun = models.PositiveIntegerField(  verbose_name=_("Minimum Countete:"),blank=True, null=True,)

##################
    def clean(self):
        errors={}
        firscoun = products_lower_bound_map[self.id]
        if self.count < firscoun:
           errors['min_count']= f'The min count must be greater than {firscoun}.'

        if errors:
            raise ValidationError(errors)

 

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

  • 0
بتاريخ 20 دقائق مضت قال Zeina Almakdisi:
firscoun = products_lower_bound_map[self.id]

أعتقد أن المشكلة في السطر هذا، كيف تقومين بكتابة قاموس الحدود الأصغرية هذا؟ أي أين تقومين بتعريفه و كيف؟

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

  • 0
بتاريخ منذ ساعة مضت قال Kais Hasan:

أعتقد أن المشكلة في السطر هذا، كيف تقومين بكتابة قاموس الحدود الأصغرية هذا؟ أي أين تقومين بتعريفه و كيف؟

firstcoun=Product.objects.get(self.id).firscoun

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

  • 0
بتاريخ 13 دقائق مضت قال Zeina Almakdisi:

firstcoun=Product.objects.get(self.id).firscoun

يمكنك جلب الحد الاصغري من self، أي يكون الكود الخاص بك كما يلي:

class Product(models.Model):
....
    firscoun = models.PositiveIntegerField(  verbose_name=_("Minimum Countete:"),blank=True, null=True,)

##################
    def clean(self):
        errors={}
        if self.count < self.firscoun:
           errors['min_count']= f'The min count must be greater than {firscoun}.'

        if errors:
            raise ValidationError(errors)

هل يمكنك تجربة أن تقومي بإضافة منتج من صفحة الأدمن بعد هذا التعديل؟ أعتقد أنه يجب استدعاء الطريقة clean بشكل يدوي قبل عمل save للمودل، يمكن القيام بذلك عن طريق كتابة الطريقة save للقيام بذلك قبل استدعاء العملية save الاصلية، أي كما يلي:

def save(self, *args, **kwargs):
  self.clean()
  super(Product, self).save(*args, **kwargs)

طبعاً نضع هذه الدالة في ال model الخاص بالمنتج، أي مع الدالة clean.

طبعاً عندها في المكان الذي يتم فيه إنشاء منتج جديد يجب القيام بكتابة try..except لالتقاط الخطأ الذي نرميه في الدالة clean.

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

  • 0
بتاريخ 12 دقائق مضت قال Kais Hasan:

يمكنك جلب الحد الاصغري من self، أي يكون الكود الخاص بك كما يلي:

class Product(models.Model):
....
    firscoun = models.PositiveIntegerField(  verbose_name=_("Minimum Countete:"),blank=True, null=True,)

##################
    def clean(self):
        errors={}
        if self.count < self.firscoun:
           errors['min_count']= f'The min count must be greater than {firscoun}.'

        if errors:
            raise ValidationError(errors)

هل يمكنك تجربة أن تقومي بإضافة منتج من صفحة الأدمن بعد هذا التعديل؟ أعتقد أنه يجب استدعاء الطريقة clean بشكل يدوي قبل عمل save للمودل، يمكن القيام بذلك عن طريق كتابة الطريقة save للقيام بذلك قبل استدعاء العملية save الاصلية، أي كما يلي:

def save(self, *args, **kwargs):
  self.clean()
  super(Product, self).save(*args, **kwargs)

طبعاً نضع هذه الدالة في ال model الخاص بالمنتج، أي مع الدالة clean.

طبعاً عندها في المكان الذي يتم فيه إنشاء منتج جديد يجب القيام بكتابة try..except لالتقاط الخطأ الذي نرميه في الدالة clean.

عند تطبيق الحل يظهر خطأ 

Product object has no attributes 'count'

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

  • 0
بتاريخ 4 دقائق مضت قال Zeina Almakdisi:

عند تطبيق الحل يظهر خطأ 

Product object has no attributes 'count'

مرحبًا زينا، 

حاولي تجربة الحل التالي:

 استخدام cleaned_data بدلاً من self في دالة clean_count، حيث تحتوي cleaned_data على البيانات المدخلة من قبل المستخدم والتي تم تنقيحها (cleaned) من قبل Django. وعند الوصول إلى الحقل product_name، يمكن استخدامه لاسترداد العنصر من قاعدة البيانات باستخدام get بدلاً من filter. ويمكن تعديل clean_count بالشكل التالي:

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = '__all__'
    count = forms.IntegerField(widget=forms.NumberInput(attrs={'min': '0'}))

    def clean_count(self):
        count = self.cleaned_data['count']
        product = Product.objects.get(product_name=self.cleaned_data['product_name'])
        firscoun = product.firscoun
        if count < firscoun:
                raise forms.ValidationError(f'The minimum count for this product is {firscoun}.')
        return count

أما بالنسبة لمشكلة استبدال product_name بـ id، يجب استخدام self.instance.pk بدلاً من self.id، حيث يمثل self.instance.pk مفتاح الأساسي للكائن الحالي. ويمكن تعديل clean بالشكل التالي:

class Product(models.Model):
    ...
    firscoun = models.PositiveIntegerField(verbose_name=_("Minimum Countete:"), blank=True, null=True)

    def clean(self):
        errors = {}
        firscoun = self.firscoun
        if self.count < firscoun:
            errors['min_count'] = f'The min count must be greater than {firscoun}.'

        if errors:
            raise ValidationError(errors)

ملاحظة: تحتاج clean إلى تعديل لتعمل بشكل صحيح، حيث يجب استخدام self.count بدلاً من self.cleaned_data['count'].

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

  • 0
بتاريخ 6 دقائق مضت قال Zeina Almakdisi:

عند تطبيق الحل يظهر خطأ 

Product object has no attributes 'count'

أنا لم أقم بكتابة المودل كاملاً، أي في حال لم يكن في المودل قد تم تعريف count فسيظهر الخطأ.

في حال كان هناك count، جربي استدعاء full_clean بدلاً من clean في الدالة save.

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

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...