জ্যাঙ্গো প্রকল্পে সিগন্যাল হ্যান্ডলারদের কোথায় বাস করা উচিত?


143

আমি সবেমাত্র একটি জ্যাঙ্গো প্রকল্পে সংকেত শ্রোতাদের বাস্তবায়ন শুরু করেছি। আমি বুঝতে পারছি যে তারা কী এবং কীভাবে সেগুলি ব্যবহার করবেন। আমার কোথায় রাখা উচিত তা নির্ধারণ করার জন্য আমার খুব কষ্ট হচ্ছে। জ্যাঙ্গো সাইট থেকে প্রাপ্ত নথিতে এই কথাটি আছে:

এই কোডটি কোথায় বাস করা উচিত?

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

যদিও এটি একটি ভাল পরামর্শ, আমার মডেলগুলিতে নন মডেল ক্লাস বা পদ্ধতি থাকা আমাকে কেবল ভুল উপায়ে ঘষে।

তাহলে, সংকেত হ্যান্ডলারগুলি সংরক্ষণ এবং নিবন্ধনের জন্য সেরা অনুশীলন / নিয়ম কী?

উত্তর:


41

আমি প্রকৃতপক্ষে তাদেরকে মডেলটিরই শ্রেণিবদ্ধ করতে চাই। এটি সবকিছুকে এক শ্রেণীর মধ্যে রাখে এবং এর অর্থ আপনাকে কোনও কিছু আমদানি করার বিষয়ে চিন্তা করতে হবে না।


2
এবং যেখানে আপনি সাধারণত সংকেতগুলির সাথে হ্যান্ডলারগুলি সংযুক্ত করেন?
ডেটাগ্রিড

1
@ ডেটাগ্রিড: প্রাসঙ্গিক মডেলগুলির নীচে.পি।
ড্যানিয়েল রোজম্যান 19

102
আপনি যদি সেই মডেলটির দ্বারা নির্গত সংকেতগুলি শুনছেন তবে সমস্ত শ্রোতাদের সেখানে রাখা পুরো ব্যায়ামকে অর্থহীন করে তোলে, তাই না? সংকেতগুলির বিন্দুটি ডিকোপল করা। শ্রোতাদের কি এই দূরবর্তী ইভেন্টগুলিতে আগ্রহী কোডের সাথে বাস করা উচিত নয়? প্রশ্নটি কীভাবে শ্রোতার উদ্বোধনের আগে লোড হয় ensure
জন

আমার ক্ষেত্রে আমি মডেলের একটি সংকেত শুনতে চাই Fooযা এর অংশ fooapp। তবে সিগন্যাল রিসিভারটি একটি এক্সটেনশন এবং ভিন্ন অ্যাপে লাইভ করে (উদাহরণস্বরূপ otherapp)।
গেটলি

2
জন মি এর বক্তব্য অনুসারে এটি কেবল সংরক্ষণ () ইত্যাদির চেয়ে ওভাররাইডিংয়ের চেয়ে খুব বেশি আলাদা নয়
ম্যাট

245

এই যোগ করা হয়েছিল ডকুমেন্টেশন যখন জ্যাঙ্গো 1.7 মুক্তি:

কড়া কথায় বলতে গেলে, সিগন্যাল হ্যান্ডলিং এবং রেজিস্ট্রেশন কোড আপনার পছন্দ মতো যে কোনও জায়গায় বাস করতে পারে, যদিও অ্যাপ্লিকেশনটির মূল মডিউল এবং এর মডেলগুলির মডিউলটি আমদানি কোডের পার্শ্ব-প্রতিক্রিয়া হ্রাস করার জন্য এড়ানো বাঞ্ছনীয়।

অনুশীলনে, সংকেত হ্যান্ডলারগুলি সাধারণত তারা সম্পর্কিত অ্যাপ্লিকেশনটির সিগন্যাল সাবমডিউলে সংজ্ঞায়িত হয়। সিগন্যাল রিসিভারগুলি আপনার অ্যাপ্লিকেশন কনফিগারেশন ক্লাসের প্রস্তুত () পদ্ধতিতে সংযুক্ত রয়েছে। আপনি যদি রিসিভার () সাজসজ্জার ব্যবহার করে থাকেন তবে কেবল প্রস্তুত অভ্যন্তরের সিগন্যাল সাবমডিউলটি আমদানি করুন)

জাজানো ১.7 এ পরিবর্তন করা হয়েছে: যেহেতু জ্যাঙ্গোর আগের সংস্করণগুলিতে প্রস্তুত () উপস্থিত ছিল না, তাই সাধারণত সিগন্যাল নিবন্ধন মডেলগুলির মডিউলে ঘটে।

সেরা অনুশীলন হ্যান্ডলারের মধ্যে আপনার হ্যান্ডলারগুলি সংজ্ঞায়িত করা হয় pyপি একটি সিগন্যাল সাবমডিউলে, উদাহরণস্বরূপ এমন একটি ফাইল যা:

ইউর্যাপ / সিগন্যাল / হ্যান্ডলার.পি :

from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import MyModel

@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
    pass

আপনার সিগন্যাল হ্যান্ডলারটি নিবন্ধ করার সেরা জায়গাটি তখন প্রস্তুত () পদ্ধতি ব্যবহার করে অ্যাপ্লিকেশনটির অ্যাপকনফিগে রয়েছে it এটি এর মতো দেখাবে:

yourapp / apps.py :

from django.apps import AppConfig

class TasksConfig(AppConfig):
    name = 'tasks'
    verbose_name = "Tasks"

    def ready(self):
        import yourproject.yourapp.signals.handlers #noqa

আপনার অ্যাপসফোনফিগটি সরাসরি আপনার সেটিংস.পিসির INSTALLED_APPS এ বা __init__আপনার অ্যাপ্লিকেশনটিতে নির্দিষ্ট করে আপনার অ্যাপকনফিগটি লোড করা হচ্ছে তা নিশ্চিত করুন। আরও তথ্যের জন্য প্রস্তুত ডকুমেন্টেশন দেখুন।

দ্রষ্টব্য: আপনি যদি অন্য অ্যাপ্লিকেশনগুলিকেও খুব ভালভাবে শোনার জন্য সংকেত সরবরাহ করে থাকেন তবে সেগুলি __init__আপনার সিগন্যাল মডিউলে রাখুন, উদাহরণস্বরূপ এমন ফাইল যা:

yourapp / সংকেত / __ init__.py

import django.dispatch

task_generate_pre_save = django.dispatch.Signal(providing_args=["task"])

এর পরে অন্য অ্যাপ্লিকেশনটি আপনার সিগন্যালটি আমদানি করে এবং এটি রেজিস্টার করে শুনতে পারে, যেমন from yourapp.signals import task_generate_pre_save। আপনার হ্যান্ডলারগুলির থেকে আপনার সিগন্যাল পৃথক করা জিনিস পরিষ্কার রাখে।

জাজানো 1.6 এর জন্য নির্দেশনা:

আপনি যদি এখনও জ্যাঙ্গো ১.6 বা তার চেয়ে কম স্থানে আটকে থাকেন তবে আপনি একই জিনিসটি করবেন (ইউর্যাপ / সিগন্যাল / হ্যান্ডলার্স.পিতে আপনার হ্যান্ডলারগুলি সংজ্ঞায়িত করুন) তবে অ্যাপকনফিগ ব্যবহার না করে আপনি হ্যান্ডলারগুলি __init__.py এর মাধ্যমে লোড করবেন আপনার অ্যাপ্লিকেশন, যেমন:

yourapp / __ init__.py

import signals

এটি প্রস্তুত () পদ্ধতিটি ব্যবহার করার মতো সুন্দর নয় কারণ এটি প্রায়শই বিজ্ঞপ্তি আমদানির সমস্যার কারণ হয়ে থাকে।


3
যেমন ডকুমেন্টেশনটি আপনাকে প্রস্তুত ওভাররাইডের কথা বলেছে, আপনি সুপার (রিপোর্টস কনফিগ, স্ব) এর মতো কিছু করতে চাইতে পারেন readyডিয়ার () যদি জাজাও কখনও কোনও কিছু নিয়ে প্রস্তুত () তৈরি করার সিদ্ধান্ত নেয় (বর্তমানে 1.7.0 হিসাবে এটি খালি)
w- -

3
আমি মনে করি এই উত্তরটি সর্বোত্তম কারণ আমদানি থেকে প্রাপ্ত পার্শ্ব-প্রতিক্রিয়াগুলিকে সম্বোধন করা একমাত্র এটি। আমি এখানে সেরা অনুশীলনগুলির সন্ধান করতে এসেছি, কারণ আমি একটি অ্যাপ্লিকেশন পরিষ্কার করছি, যা এই ধরণের পার্শ্বপ্রতিক্রিয়ার কারণে ঠিক ভেঙে গেছে। হায়, অ্যাপ্লিকেশনটি জাজানো ১.6 এ চলছে এবং সেরা অনুশীলনগুলি কেবল জাজানো ১.7 এ কাজ করে। __init__আমদানি সংকেতকে দেওয়া দেওয়ার অস্থায়ী কাজটি আমার পক্ষে কাজ করবে না, তাই আমি অবাক হয়েছি যে আমরা পরে জ্যাঙ্গো সংস্করণে আপগ্রেড করার জন্য প্রস্তুত না হওয়া পর্যন্ত সিগন্যাল আমদানি করতে পারার মতো অন্য কোনও জায়গা রয়েছে কিনা I
ক্যাস্পারড

সেখানে from . import handlers(বা অনুরূপ) থাকা উচিত নয় yourapp/signals/__init__.py?
ধোবস

আপনি কি কোথাও হ্যান্ডলারের.পি মডিউলটি আমদানি করবেন না? আমি এটি চেষ্টা করছি এবং এটি সংকেতের জন্য হ্যান্ডলারটি সংজ্ঞায়িত করছে বলে মনে হচ্ছে না।
অ্যান্ড্রেস

1
fww yourproject.টাস্কনফিগ ক্লাস কোড ব্লকের শেষ লাইনে আমার দরকার নেই । আমি ঠিক এই কাঠামোর সাথে এই কাজ পেয়েছি, সুতরাং এই QA বিবেচনা করুন :)
গ্রেগ Kaleka

40

আমি কেবল এটি পেরিয়ে এসেছি এবং আমার সংকেতগুলি মডেল-সম্পর্কিত নয় বলে আমি ভেবেছিলাম যে আমি আমার সমাধান যুক্ত করব।

আমি লগ ইন / লগ আউট এর চারপাশে বিভিন্ন ডেটা লগ করছি এবং হুক ইন করা দরকার django.contrib.auth.signals

আমি সিগন্যাল হ্যান্ডলারগুলিকে একটি signals.pyফাইলে রেখেছি এবং তারপরে __init__.pyমডিউল ফাইল থেকে সিগন্যাল আমদানি করেছি, কারণ আমার বিশ্বাস অ্যাপ্লিকেশন শুরু হওয়ার সাথে সাথেই এটি ডাকা হবে (একটি printবিবৃতি দিয়ে পরীক্ষা করা পরামর্শ দেয় যে সেটিংস ফাইলটি পড়ার আগেই এটি ডাকা হয়েছিল।)

# /project/__init__.py
import signals

এবং সিগন্যাল.পি

# /project/signals.py
from django.contrib.auth.signals import user_logged_in

def on_logged_in(sender, user, request, **kwargs):
    print 'User logged in as: \'{0}\''.format(user)

user_logged_in.connect(on_logged_in)

আমি জ্যাঙ্গোতে (/ অজগর) খুব নতুন, তাই যে কেউ আমাকে বলছেন যে এটি একটি ভয়ানক ধারণা!


3
এটি যৌক্তিক মনে হয় তবে আমি এটি অ্যাপ্লিকেশন পর্যায়ে করার পরামর্শ দেব।
নীল

2
সাবধান, এই যুক্তি সম্ভবত ডুপ্লিকেট সিগন্যাল beign বহিষ্কার করা হবে। user_logged_in.connect(on_logged_in)সম্ভবত dispatch_uidযুক্তিটি পাস করা উচিত । ডকস.ডজ্যাঙ্গোপ্রজেক্ট / এএন / দেবী / টপিক্স / সিগন্যালস / এ আরও ।
স্কট কোটস

তার জন্য ধন্যবাদ - জানতে পেরে ভাল। আমি এই পদ্ধতিটি ব্যবহার করে সমস্ত লগইন লগইন করছি (আইপি / ব্যবহারকারী এজেন্ট রেকর্ডিং) এবং এখনও পর্যন্ত কোনও সদৃশ নেই - যদিও এর অর্থ এই নয় যে লাইনের নীচে একটি ছোট পরিবর্তন কোনও সমস্যা সৃষ্টি করবে না!
হুগো রজার-ব্রাউন 10

13

আমি যখন সম্প্রতি আপনার প্রকল্পগুলি / অ্যাপ্লিকেশনগুলি রাখার কথা বলি তখন সেরা অনুশীলনগুলি সম্পর্কে এই নিবন্ধটি পড়েছি এবং এটি পরামর্শ দেয় যে আপনার সমস্ত কাস্টম প্রেরণকারী সংকেতগুলিকে ডাকা একটি ফাইলে যেতে হবে signals.py। যাইহোক, এটি আপনার সমস্যার পুরোপুরি সমাধান করে না, যেহেতু আপনার এখনও এগুলি অন্য কোথা থেকে আমদানি করা দরকার এবং পূর্বের তারা আরও ভালভাবে আমদানি করতে পারেন।

মডেল পরামর্শটি একটি ভাল। যেহেতু আপনি ইতিমধ্যে আপনার signals.pyফাইলে সমস্ত কিছু সংজ্ঞায়িত করেছেন তাই এটি ফাইলের শীর্ষে একটি লাইনের বেশি নেওয়া উচিত নয়। এটি admin.pyফাইলটি যেভাবে সাজানো হয়েছে তার অনুরূপ (উপরে শ্রেণীর সংজ্ঞা এবং নীচে সমস্ত কাস্টম অ্যাডমিন ক্লাস নিবন্ধকরণের কোড সহ), আপনি যদি নিজের সিগন্যালগুলি সংজ্ঞায়িত করেন তবে সেগুলি একই ফাইলটিতে সংযুক্ত করুন।

আশা করি এইটি কাজ করবে! শেষ পর্যন্ত এটি আপনার পছন্দের দিকে নেমে আসে।


1
আমি আমার সিগন্যাল হ্যান্ডলারগুলিও একটি signals.pyফাইলে রাখতে চেয়েছিলাম , তবে কীভাবে পরে এটি কল করা উচিত তা জানতাম না। এটি আমার models.pyফাইলে আমদানি করে আমার মডেল.পি ফাইলটিকে "দূষিত" না করে আমি খুব পরিষ্কার সমাধান পেয়েছি। ধন্যবাদ! :)
ড্যানিলো বার্গেন

10
সেখানে একটি ক্রস-আমদানি রয়েছে: সংকেত.পি মডেল.পি থেকে মডেল আমদানি করার চেষ্টা করে
ইভান ভাইরাবায়ান

8

প্রতিটি অ্যাপ্লিকেশনে মডেল.পি এবং সিগন্যাল.পি হ'ল সিগন্যালগুলি সংযুক্ত করার জন্য প্রস্তাবিত স্থান ছিল, তবে, আমার মতে, সিগন্যালগুলি এবং হ্যান্ডলারগুলি প্রেরণে রাখার জন্য এটি সর্বোত্তম সমাধান নয়। জ্যাঙ্গোতে আবিষ্কারের কারণ সংকেত এবং হ্যান্ডলারগুলি প্রেরণ করা উচিত।

আমি দীর্ঘদিন ধরে লড়াই করে যাচ্ছিলাম এবং অবশেষে আমরা সমাধানটি বের করেছিলাম।

অ্যাপ ফোল্ডারে একটি সংযোগকারী মডিউল তৈরি করুন

তাহলে আমাদের আছে:

app/
    __init__.py
    signals.py
    models.py
    connectors.py

অ্যাপ্লিকেশন / সংযোজকগুলিতে, আমরা সংকেত হ্যান্ডলারগুলি সংজ্ঞায়িত করেছি এবং তাদের সাথে সংযুক্ত করি। একটি উদাহরণ সরবরাহ করা হয়:

from signals import example_signal
from models import ExampleModel
from django.db.models.signals import post_save, post_delete

def hanndler(sender, *args, **kwargs):
    pass

post_save.connect(hander, sender=ExampleModel)

তারপরে মডেল.পাইতে, আমরা ফাইলটির শেষে নিম্নলিখিত লাইনটি যুক্ত করব:

from app import connector

এখানে সবকিছু করা হয়েছে।

এইভাবে, আমরা সংকেত.পিতে সংকেতগুলি এবং সংযোগকারী.পিতে সমস্ত হ্যান্ডলারগুলি রাখতে পারি py মডেল এবং সিগন্যালে কোনও গণ্ডগোল নেই।

আশা করি এটি আরও একটি সমাধান সরবরাহ করে।


1
তাহলে কি সিগন্যাল.পি যায়? আপনার উদাহরণ থেকে দেখে মনে হচ্ছে এটি কেবলমাত্র কাস্টম সংকেত। সাধারণত আমরা কেবল সংকেত এবং সংযোজকগুলিকে একত্রিত করি কারণ বেশিরভাগের কাস্টম সংকেত থাকবে না।
aloreলোর

@ডলোর হ্যাঁ, সমস্ত কাস্টম সংকেত সিগন্যাল.পিতে দেওয়া হয়। আমাদের অনেক কাস্টমাইজড সংকেত রয়েছে। তবে আপনার যদি অনেকগুলি না থাকে তবে এই ফাইলটি বাদ দেওয়া যেতে পারে।
সামুয়েল

@dal যেমন একই প্রশ্ন
olleh

1
এই সমস্ত এখন পুরানো পরামর্শ নোট, জ্যাঙ্গো উপায় এখন সিগন্যাল হ্যান্ডলার যেখানে থাকেন হ্যান্ডলারগুলি আমদানি করতে appconfig ব্যবহার করা হয়। এবং সিগন্যালে.পি যান কাস্টম সিগন্যালগুলিতে
ডুরোর

3

আমি তাদের আলাদা আলাদা ফাইলে রাখি signals.py, models.pyসমস্ত মডেল সংজ্ঞায়িত হওয়ার পরে। আমি সেগুলি আমদানি করি এবং সংকেতগুলিতে মডেলগুলি সংযুক্ত করি।

signals.py

#  necessary imports

def send_mail_on_save(<args>):
    # code here 

models.py

# imports
class mymodel(models.Model):
    # model here

# import signals
from signals import send_mail_on_save
# connect them 
post_save.connect(send_mail_on_save,sender=mymodel)

এটি আমাকে যৌক্তিক বিচ্ছেদ দেয়, অবশ্যই তাদের মডেল.পিতে রাখার ক্ষেত্রে কোনও ভুল নেই , তবে এটি এইভাবে আরও পরিচালনাযোগ্য।

আশাকরি এটা সাহায্য করবে!!


আপনি "সিগন্যাল.পি" -তে সিগন্যাল হ্যান্ডলার রাখছেন, আমরা যদি এর নাম রাখি "হ্যান্ডলারস.পি"
আবদুল ফাতাহ

1
আপনি ফাইলকে সিগন্যাল.পি বা হ্যান্ডেলআরপি হিসাবে নাম দেন কিনা তা বিবেচ্য নয়। এটি নিয়ম নয় কেবল একটি সম্মেলন।

3

সম্পর্কে ছোট অনুস্মারক AppConfig। সেট করতে ভুলবেন না:

# yourapp/__init__.py

default_app_config = 'yourapp.apps.RockNRollConfig'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.