দেখে মনে হচ্ছে আপনি ডেটা মডেল এবং ডোমেন মডেলের মধ্যে পার্থক্য সম্পর্কে জিজ্ঞাসা করছেন - পরেরটি হ'ল আপনি যেখানে আপনার শেষ ব্যবহারকারীর দ্বারা উপলব্ধ ব্যবসায়িক যুক্তি এবং সত্ত্বাগুলি খুঁজে পেতে পারেন, পূর্ববর্তীটি যেখানে আপনি আসলে আপনার ডেটা সঞ্চয় করেন।
তদুপরি, আমি আপনার প্রশ্নের তৃতীয় অংশটি ব্যাখ্যা করেছি: এই মডেলগুলিকে আলাদা রাখতে কীভাবে ব্যর্থতা লক্ষ্য করা যায়।
এগুলি দুটি খুব আলাদা ধারণা এবং এগুলি পৃথক রাখা সবসময় শক্ত। তবে, কিছু সাধারণ নিদর্শন এবং সরঞ্জাম রয়েছে যা এই উদ্দেশ্যে ব্যবহার করা যেতে পারে।
ডোমেন মডেল সম্পর্কে
আপনাকে প্রথমে যে জিনিসটি সনাক্ত করতে হবে তা হ'ল আপনার ডোমেন মডেলটি আসলে ডেটা সম্পর্কে নয়; এটি "এই ব্যবহারকারীকে সক্রিয় করুন", "এই ব্যবহারকারীকে নিষ্ক্রিয় করুন", "বর্তমানে ব্যবহারকারীরা সক্রিয় রয়েছে?", এবং "এই ব্যবহারকারীর নাম কী?" এর মতো ক্রিয়া এবং প্রশ্নগুলির বিষয়ে । ক্লাসিকাল ভাষায়: এটি প্রশ্ন এবং কমান্ড সম্পর্কে ।
কমান্ডে চিন্তা করা
আসুন আপনার উদাহরণে কমান্ডগুলি দেখে শুরু করুন: "এই ব্যবহারকারীকে সক্রিয় করুন" এবং "এই ব্যবহারকারীকে নিষ্ক্রিয় করুন"। কমান্ডগুলি সম্পর্কে দুর্দান্ত জিনিসটি হ'ল যখন সেগুলি তখনকার দৃশ্যের দ্বারা ছোট্ট দ্বারা সহজেই প্রকাশ করা যায়:
নিষ্ক্রিয় ব্যবহারকারীর দেওয়া
যখন প্রশাসক এই ব্যবহারকারীকে সক্রিয় করে
তখন ব্যবহারকারী সক্রিয় হয়ে যায়
এবং ব্যবহারকারীর কাছে একটি নিশ্চিতকরণ ই-মেল প্রেরণ করা হয়
এবং সিস্টেম লগ
(ইত্যাদি ইত্যাদি) এ একটি এন্ট্রি যুক্ত করা হয়
আপনার অবকাঠামোর বিভিন্ন অংশ কীভাবে একক কমান্ড দ্বারা প্রভাবিত হতে পারে তা দেখার জন্য এই জাতীয় দৃশ্যাবলী কার্যকর - এই ক্ষেত্রে আপনার ডাটাবেস (কিছু ধরণের 'সক্রিয়' পতাকা), আপনার মেল সার্ভার, আপনার সিস্টেম লগ ইত্যাদি etc.
এই জাতীয় পরিস্থিতি আপনাকে একটি পরীক্ষা চালিত বিকাশের পরিবেশ স্থাপনে সত্যই সহায়তা করে।
এবং শেষ অবধি, আদেশগুলিতে চিন্তা করা আপনাকে কার্য-ভিত্তিক অ্যাপ্লিকেশন তৈরি করতে সহায়তা করে। আপনার ব্যবহারকারীরা এটি প্রশংসা করবে :-)
কমান্ড প্রকাশ করা
জাজানো কমান্ড প্রকাশের দুটি সহজ উপায় সরবরাহ করে; এগুলি উভয়ই বৈধ বিকল্প এবং দুটি পদ্ধতির মিশ্রণটি অস্বাভাবিক কিছু নয়।
পরিষেবা স্তর
সেবা মডিউল ইতিমধ্যে হয়েছে @Hedde দ্বারা বর্ণিত । এখানে আপনি একটি পৃথক মডিউল নির্ধারণ করেন এবং প্রতিটি কমান্ড একটি ফাংশন হিসাবে উপস্থাপিত হয়।
services.py
def activate_user(user_id):
user = User.objects.get(pk=user_id)
# set active flag
user.active = True
user.save()
# mail user
send_mail(...)
# etc etc
ফর্ম ব্যবহার করে
অন্য উপায়টি হ'ল প্রতিটি কমান্ডের জন্য জ্যাঙ্গো ফর্ম ব্যবহার করা। আমি এই পদ্ধতির পছন্দ করি, কারণ এটি একাধিক ঘনিষ্ঠভাবে সম্পর্কিত দিকগুলি একত্রিত করে:
- কমান্ড কার্যকর (এটি কি করে?)
- কমান্ড প্যারামিটারগুলির বৈধতা (এটি কি এটি করতে পারে?)
- কমান্ডের উপস্থাপনা (আমি এটি কীভাবে করব?)
forms.py
class ActivateUserForm(forms.Form):
user_id = IntegerField(widget = UsernameSelectWidget, verbose_name="Select a user to activate")
# the username select widget is not a standard Django widget, I just made it up
def clean_user_id(self):
user_id = self.cleaned_data['user_id']
if User.objects.get(pk=user_id).active:
raise ValidationError("This user cannot be activated")
# you can also check authorizations etc.
return user_id
def execute(self):
"""
This is not a standard method in the forms API; it is intended to replace the
'extract-data-from-form-in-view-and-do-stuff' pattern by a more testable pattern.
"""
user_id = self.cleaned_data['user_id']
user = User.objects.get(pk=user_id)
# set active flag
user.active = True
user.save()
# mail user
send_mail(...)
# etc etc
প্রশ্নে চিন্তা করছেন
আপনার উদাহরণে কোনও প্রশ্ন নেই, তাই আমি কয়েকটি দরকারী প্রশ্ন তৈরির স্বাধীনতা নিয়েছি। আমি "প্রশ্ন" শব্দটি ব্যবহার করতে পছন্দ করি তবে প্রশ্নগুলি হল ধ্রুপদী পরিভাষা। আকর্ষণীয় প্রশ্নগুলি হ'ল: "এই ব্যবহারকারীর নাম কী?", "এই ব্যবহারকারী কি লগ ইন করতে পারবেন?", "আমাকে নিষ্ক্রিয় ব্যবহারকারীদের একটি তালিকা দেখান", এবং "নিষ্ক্রিয় ব্যবহারকারীদের ভৌগলিক বিতরণ কী?"
এই প্রশ্নের উত্তর দেওয়ার আগে, আপনার সর্বদা নিজেকে দুটি প্রশ্ন জিজ্ঞাসা করা উচিত: এটি কি কেবলমাত্র আমার টেম্পলেটগুলির জন্য একটি উপস্থাপিত ক্যোয়ারী এবং / অথবা আমার কমান্ডগুলি কার্যকর করার সাথে যুক্ত একটি ব্যবসায়িক লজিক কোয়েরি, এবং / অথবা একটি রিপোর্টিং কোয়েরি।
উপস্থাপনা সম্পর্কিত প্রশ্নগুলি কেবলমাত্র ব্যবহারকারী ইন্টারফেসের উন্নতির জন্য করা হয়। ব্যবসায়ের যুক্তিযুক্ত প্রশ্নের প্রশ্নের উত্তরগুলি আপনার আদেশগুলি কার্যকর করতে সরাসরি প্রভাবিত করে। রিপোর্টিং ক্যোয়ারী নিছক বিশ্লেষণাত্মক উদ্দেশ্যে এবং দীর্ঘ সময়সীমাবদ্ধতা রয়েছে। এই বিভাগগুলি পারস্পরিক একচেটিয়া নয়।
অন্য প্রশ্নটি হ'ল: "উত্তরগুলির কি আমার সম্পূর্ণ নিয়ন্ত্রণ আছে?" উদাহরণস্বরূপ, ব্যবহারকারীর নাম জিজ্ঞাসা করার সময় (এই প্রসঙ্গে) ফলাফলের উপর আমাদের কোনও নিয়ন্ত্রণ নেই, কারণ আমরা একটি বাহ্যিক এপিআইয়ের উপর নির্ভর করি।
প্রশ্ন করা
জাজানোতে সর্বাধিক প্রাথমিক ক্যোয়ারী হ'ল ম্যানেজার অবজেক্টের ব্যবহার:
User.objects.filter(active=True)
অবশ্যই, এটি কেবল তখনই কাজ করে যদি ডেটা আপনার ডেটা মডেলটিতে প্রকৃতপক্ষে উপস্থাপন করা হয়। এই সবসময় তা হয় না। এই ক্ষেত্রে, আপনি নীচের বিকল্পগুলি বিবেচনা করতে পারেন।
কাস্টম ট্যাগ এবং ফিল্টার
প্রথম বিকল্পটি কেবলমাত্র উপস্থাপনামূলক প্রশ্নের জন্য দরকারী: কাস্টম ট্যাগ এবং টেম্পলেট ফিল্টার।
template.html
<h1>Welcome, {{ user|friendly_name }}</h1>
template_tags.py
@register.filter
def friendly_name(user):
return remote_api.get_cached_name(user.id)
অনুসন্ধান পদ্ধতি
যদি আপনার প্রশ্নের নিছক প্রেজেন্টেশন না হয় তবে আপনি আপনার টু প্রশ্নের যোগ করতে পারিনি services.py (যদি আপনি যে ব্যবহার করছেন), অথবা পরিচয় করিয়ে queries.py মডিউল:
queries.py
def inactive_users():
return User.objects.filter(active=False)
def users_called_publysher():
for user in User.objects.all():
if remote_api.get_cached_name(user.id) == "publysher":
yield user
প্রক্সি মডেল
প্রক্সি মডেলগুলি ব্যবসায়ের যুক্তি এবং প্রতিবেদনের প্রসঙ্গে খুব কার্যকর। আপনি মূলত আপনার মডেলের একটি বর্ধিত উপসেট সংজ্ঞায়িত করেন। Manager.get_queryset()
পদ্ধতিটি ওভাররাইড করে আপনি কোনও পরিচালকের বেস ক্যোয়ারীসেটকে ওভাররাইড করতে পারেন ।
models.py
class InactiveUserManager(models.Manager):
def get_queryset(self):
query_set = super(InactiveUserManager, self).get_queryset()
return query_set.filter(active=False)
class InactiveUser(User):
"""
>>> for user in InactiveUser.objects.all():
… assert user.active is False
"""
objects = InactiveUserManager()
class Meta:
proxy = True
অনুসন্ধান মডেল
অন্তর্নিহিত জটিল, কিন্তু বেশিরভাগ ক্ষেত্রে কার্যকর করা হয় এমন প্রশ্নের জন্য, কোয়েরি মডেলগুলির সম্ভাবনা রয়েছে। একটি ক্যোয়ারী মডেল হ'ল ডেনারালাইমাইজেশনের একটি ফর্ম যেখানে একক ক্যোয়ারীর জন্য প্রাসঙ্গিক ডেটা আলাদা মডেলে সংরক্ষণ করা হয়। অবশ্যই কৌশলটি হ'ল ডেনারমালাইজড মডেলটিকে প্রাথমিক মডেলের সাথে সুসংগত করে রাখা। পরিবর্তনগুলি পুরোপুরি আপনার নিয়ন্ত্রণে থাকলেই ক্যোয়ারী মডেলগুলি ব্যবহার করা যেতে পারে।
models.py
class InactiveUserDistribution(models.Model):
country = CharField(max_length=200)
inactive_user_count = IntegerField(default=0)
প্রথম বিকল্পটি হ'ল আপনার আদেশগুলিতে এই মডেলগুলি আপডেট করা update এই মডেলগুলি কেবল এক বা দুটি কমান্ড দ্বারা পরিবর্তিত হলে এটি খুব কার্যকর।
forms.py
class ActivateUserForm(forms.Form):
# see above
def execute(self):
# see above
query_model = InactiveUserDistribution.objects.get_or_create(country=user.country)
query_model.inactive_user_count -= 1
query_model.save()
একটি ভাল বিকল্প কাস্টম সংকেত ব্যবহার করা হবে। এই সংকেত অবশ্যই আপনার আদেশ দ্বারা নির্গত হয়। সংকেতগুলির সুবিধা রয়েছে যে আপনি একাধিক ক্যোয়ারী মডেলগুলি আপনার মূল মডেলের সাথে সিঙ্ক করে রাখতে পারেন। তদুপরি, সিলারি বা অনুরূপ ফ্রেমওয়ার্ক ব্যবহার করে সংকেত প্রক্রিয়াকরণ ব্যাকগ্রাউন্ড কার্যগুলিতে অফলোড করা যায়।
signals.py
user_activated = Signal(providing_args = ['user'])
user_deactivated = Signal(providing_args = ['user'])
forms.py
class ActivateUserForm(forms.Form):
# see above
def execute(self):
# see above
user_activated.send_robust(sender=self, user=user)
models.py
class InactiveUserDistribution(models.Model):
# see above
@receiver(user_activated)
def on_user_activated(sender, **kwargs):
user = kwargs['user']
query_model = InactiveUserDistribution.objects.get_or_create(country=user.country)
query_model.inactive_user_count -= 1
query_model.save()
এটি পরিষ্কার রাখা
এই পদ্ধতির ব্যবহার করার সময়, আপনার কোডটি পরিষ্কার থাকে কিনা তা নির্ধারণ করা হাস্যকরভাবে সহজ হয়ে যায়। কেবল এই নির্দেশিকাগুলি অনুসরণ করুন:
- আমার মডেলটিতে এমন পদ্ধতি রয়েছে যা ডেটাবেস স্থিতি পরিচালনার চেয়ে আরও বেশি করে? আপনার একটি আদেশ বের করা উচিত।
- আমার মডেলটিতে এমন বৈশিষ্ট্য রয়েছে যা ডেটাবেস ক্ষেত্রগুলিতে ম্যাপ করে না? আপনার একটি কোয়েরি বের করা উচিত।
- আমার মডেল রেফারেন্স অবকাঠামো যা আমার ডাটাবেস নয় (যেমন মেল)? আপনার একটি আদেশ বের করা উচিত।
একই মতামতের জন্য যায় (কারণ দেখা প্রায়শই একই সমস্যায় ভোগে)।
- আমার দর্শন কি সক্রিয়ভাবে ডাটাবেস মডেলগুলি পরিচালনা করে? আপনার একটি আদেশ বের করা উচিত।
কিছু তথ্যসূত্র
জাজানো ডকুমেন্টেশন: প্রক্সি মডেল
জ্যাঙ্গো ডকুমেন্টেশন: সিগন্যাল
আর্কিটেকচার: ডোমেন ড্রাইভড ডিজাইন