জ্যাঙ্গোর মডেল কেন না? সেভ () পুরো_ক্যালান () কল করে না?


150

আমি খুব আগ্রহী যদি কেউ জানে যে জ্যাঙ্গোর orm কোনও মডেল ফর্মের অংশ হিসাবে সংরক্ষণ না করা হয় তবে কোনও মডেলটিতে 'ফুল_ক্যালান' কল করে না good

মনে রাখবেন যে আপনি যখন আপনার মডেলটির সংরক্ষণ () পদ্ধতিটি কল করবেন তখন পূর্ণ_সামান্য () স্বয়ংক্রিয়ভাবে কল হবে না। আপনি যখন নিজে নিজে তৈরি করা মডেলগুলির জন্য এক-পদক্ষেপের মডেল বৈধতা চালাতে চান তখন আপনাকে এটিকে ম্যানুয়ালি কল করতে হবে। জ্যাঙ্গোর সম্পূর্ণ ক্লিন ডক

(দ্রষ্টব্য: জ্যাঙ্গো ১.6 এর জন্য উদ্ধৃতিটি আপডেট হয়েছে ... পূর্ববর্তী জ্যাঙ্গো ডক্সে মডেলফর্মগুলি সম্পর্কেও সতর্কতা ছিল had)

লোকেরা এই আচরণটি চান না কেন এমন কোনও ভাল কারণ আছে? আমি মনে করি আপনি যদি কোনও মডেলটিতে বৈধতা যোগ করার জন্য সময় নেন, আপনি মডেলটি প্রতিবার সেভ করার সময় সেই বৈধতাটি চালাতে চান।

আমি জানি কীভাবে সবকিছু সঠিকভাবে কাজ করতে হয়, আমি কেবল একটি ব্যাখ্যা খুঁজছি।


11
এই প্রশ্নের জন্য আপনাকে অনেক ধন্যবাদ, এটি আরও অনেক সময় দেয়ালের বিরুদ্ধে মাথা ঠেকানো আমাকে থামিয়েছিল। আমি এমন একটি মিশ্রণ তৈরি করেছি যা অন্যকে সাহায্য করতে পারে। গিস্টটি দেখুন
glarrain

এবং আমি অবশেষে pre_saveহুকটি ধরতে সিগন্যালটি ব্যবহার করি full_cleanএবং সমস্ত ধরা মডেলকে করি।
আলফ্রেড হুয়াং

উত্তর:


59

আফাইক, এটি পিছনের সামঞ্জস্যের কারণে। বাদ দেওয়া ক্ষেত্রগুলির সাথে মডেলফরমগুলি, ডিফল্ট মানগুলির সাথে মডেলগুলি, প্রাক_সেজ () সংকেত ইত্যাদি রয়েছে problems

উত্স আপনি আগ্রহী হতে পারে:


3
দ্বিতীয় তথ্যসূত্র থেকে সর্বাধিক সহায়ক অংশ (আইএমএইচও): "একটি" স্বয়ংক্রিয় "বৈধতা বিকল্পটি বিকাশ করা যা উভয়ই সত্যই কার্যকর এবং সমস্ত প্রান্তের কেসগুলি পরিচালনা করতে যথেষ্ট শক্তিশালী, এটি যদি সম্ভব হয় - তবে তার চেয়ে অনেক বেশি ১.২ টাইমফ্রেমে সম্পন্ন করা যায় Hence সুতরাং, আপাতত, জ্যাঙ্গো তেমন কোনও জিনিস নেই, এবং এটি 1.2 এ থাকবে না you আপনি যদি মনে করেন যে আপনি এটি 1.3 এর জন্য কাজ করতে পারেন তবে আপনার সেরা বেট হ'ল একটি কাজ করা কমপক্ষে কিছু নমুনা কোড সহ আপনি কীভাবে এটিকে সহজ এবং মজবুত রাখবেন তার ব্যাখ্যা সহ প্রস্তাব, "।
জোশ

30

সামঞ্জস্যতার কথা বিবেচনা করার কারণে, সংরক্ষণে অটো ক্লিন জ্যাঙ্গো কার্নেলে সক্ষম করা যায় না।

যদি আমরা একটি নতুন প্রকল্প শুরু করি এবং চান যে saveমডেলটিতে ডিফল্ট পদ্ধতিটি স্বয়ংক্রিয়ভাবে পরিষ্কার হয়, তবে প্রতিটি মডেল সংরক্ষণ করার আগে আমরা পরিষ্কার করার জন্য নিম্নলিখিত সিগন্যালটি ব্যবহার করতে পারি।

from django.dispatch import receiver
from django.db.models.signals import pre_save, post_save

@receiver(pre_save)
def pre_save_handler(sender, instance, *args, **kwargs):
    instance.full_clean()

2
প্রথমে পুরো_ক্যালান কল করতে, তারপরে সুপার () কল করার জন্য কিছু বেসমোডেল (যা অন্যরা উত্তরাধিকার সূত্রে প্রাপ্ত হবে) সেভ পদ্ধতিকে ওভাররাইড করার চেয়ে কেন এটি ভাল (বা আরও খারাপ)?
জে__

7
আমি এই পদ্ধতির সাথে দুটি সমস্যা দেখতে পাচ্ছি 1) মডেলফর্মের পূর্ণ_চিকিত্সের ক্ষেত্রে () দু'বার কল করা হবে: ফর্ম এবং সংকেত দিয়ে 2) যদি ফর্মটি কিছু ক্ষেত্র বাদ দেয় তবে সেগুলি এখনও সংকেত দ্বারা বৈধ হবে।
মেহমেট

1
@mehmet সুতরাং এইসব যোগ করতে পারেন হতে পারে if send == somemodel, then exclude some fieldsমধ্যেpre_save_handler
সিমিন Jie থেকে

4
যারা এই পদ্ধতির ব্যবহার করছেন বা ব্যবহার করছেন তাদের বিবেচনা করুন: মনে রাখবেন যে এই পদ্ধতিটি আনুষ্ঠানিকভাবে জাঙ্গো দ্বারা সমর্থিত নয় এবং প্রত্যাশিত ভবিষ্যতে সমর্থন করা হবে না ( জাঙ্গো বাগ ট্র্যাকারে এই মন্তব্যটি দেখুন: কোড. djangoproject.com/ticket/ 29655 # মন্তব্য: 3 ), সুতরাং আপনি যদি সমস্ত মডেলের বৈধতা সক্ষম করে থাকেন তবে প্রমাণীকরণ কাজ করা (কোড. djangoproject.com/ticket/29655 ) এর মতো কিছু অসম্পূর্ণতায় আপনি হোঁচট খাওয়ার সম্ভাবনা রয়েছে । আপনাকে নিজেরাই এ জাতীয় সমস্যা মোকাবেলা করতে হবে। তবে এটিএম এর চেয়ে ভাল আর কোনও উপায় নেই।
ইভজেনি এ।

2
জ্যাঙ্গো ২.২.৩ অনুসারে, এটি মৌলিক প্রমাণীকরণ সিস্টেমটিতে একটি সমস্যা সৃষ্টি করে। আপনি একটি পাবেন ValidationError: Session with this Session key already exists। এটি এড়াতে, sender in list_of_model_classesজ্যাঙ্গোর ডিফল্ট প্রমাণীকরণ মডেলগুলিকে ওভাররাইড করা থেকে সংকেতটি রোধ করতে আপনার একটি আইফেট-স্টেটমেন্ট যুক্ত করতে হবে । list_of_model_classesআপনি চয়ন করুন তবে সংজ্ঞা দিন
অ্যাডিসন ক্লিনকে

15

Simpliest পথ ডাকতে full_cleanপদ্ধতি মাত্র ওভাররাইড হয় saveআপনার পদ্ধতি model:

def save(self, *args, **kwargs):
    self.full_clean()
    return super(YourModel, self).save(*args, **kwargs)

কেন এটি সিগন্যাল ব্যবহারের চেয়ে ভাল (বা আরও খারাপ)?
জে__

6
আমি এই পদ্ধতির সাথে দুটি সমস্যা দেখতে পাচ্ছি 1) মডেলফর্মের পূর্ণ_চিকিত্সের ক্ষেত্রে () দু'বার কল করা হবে: ফর্ম এবং সংরক্ষণের মাধ্যমে 2) যদি ফর্মটি কিছু ক্ষেত্র বাদ দেয় তবে সেগুলি সংরক্ষণের দ্বারা বৈধ হয়ে যাবে।
মেহমেট

3

কোড এক টুকরা যে একটি রিসিভার ঘোষণা ঢোকাতে পরিবর্তে, আমরা হিসাবে একটি অ্যাপ্লিকেশন ব্যবহার করতে পারেন INSTALLED_APPSঅধ্যায়settings.py

INSTALLED_APPS = [
    # ...
    'django_fullclean',
    # your apps here,
]

তার আগে, আপনাকে django-fullcleanপিপিআই ব্যবহার করে ইনস্টল করতে হবে :

pip install django-fullclean

13
আপনি কেন এই pip installঅ্যাপ্লিকেশনগুলিতে নিজেরাই এই লাইনগুলি লেখার পরিবর্তে 4 টি কোডের লাইন ( উত্স কোডটি পরীক্ষা করুন ) সহ কিছু অ্যাপ্লিকেশন করবেন?
ডেভিড ডি

আরেকটি গ্রন্থাগার যা আমি নিজেকে চেষ্টা করিনি: github.com/danielgatis/django-smart-save
Flimm

2

যদি আপনার এমন কোনও মডেল থাকে যা আপনি নিশ্চিত করতে চান তবে কমপক্ষে একটি এফকে সম্পর্ক রয়েছে এবং আপনি ব্যবহার করতে চান না null=Falseকারণ এটির জন্য ডিফল্ট এফকে (যা আবর্জনার ডেটা হবে) নির্ধারণ করা প্রয়োজন, আমি যেভাবে আসছি তার সেরা উপায় is কাস্টম .clean()এবং .save()পদ্ধতি যুক্ত করতে। .clean()বৈধতা ত্রুটি উত্থাপন, এবং .save()ক্লিন কল। এইভাবে অখণ্ডতা ফর্ম এবং অন্যান্য কলিং কোড, কমান্ড লাইন এবং পরীক্ষা উভয় থেকেই প্রয়োগ করা হয় en এটি ব্যতীত (এএএফআইসিটি) কোনও পরীক্ষা লেখার কোনও উপায় নেই যা নিশ্চিত করে যে কোনও মডেলের নির্দিষ্টভাবে নির্বাচিত (ডিফল্ট নয়) অন্যান্য মডেলের সাথে এফকে সম্পর্ক রয়েছে।

class Payer(models.Model):

    name = models.CharField(blank=True, max_length=100)
    # Nullable, but will enforce FK in clean/save:
    payer_group = models.ForeignKey(PayerGroup, null=True, blank=True,)

    def clean(self):
        # Ensure every Payer is in a PayerGroup (but only via forms)
        if not self.payer_group:
            raise ValidationError(
                {'payer_group': 'Each Payer must belong to a PayerGroup.'})

    def save(self, *args, **kwargs):
        self.full_clean()
        return super().save(*args, **kwargs)

    def __str__(self):
        return self.name

1

@ অ্যালফ্রেড হুয়াংয়ের উত্তর এবং এটিতে মন্তব্য সম্পর্কে মন্তব্য করা। বর্তমান মডিউল (মডেল.পি) এর ক্লাসগুলির তালিকা নির্ধারণ করে এবং প্রাক-সেভ হুকটিতে এটির বিপরীতে পরীক্ষা করে কেউ প্রাক-সেভ হুকটি লক করে কোনও অ্যাপ্লিকেশনটিতে লক করতে পারে:

CUSTOM_CLASSES = [obj for name, obj in
        inspect.getmembers(sys.modules[__name__])
        if inspect.isclass(obj)]

@receiver(pre_save)
def pre_save_handler(sender, instance, **kwargs):
    if type(instance) in CUSTOM_CLASSES:
        instance.full_clean()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.