ইতিমধ্যে একটি মহান উত্তর থেকে দানি Herrera তবে আমি আরো এটিতে সম্প্রসারিত করতে ইচ্ছুক।
দ্বিতীয় বিকল্পটিতে যেমন ব্যাখ্যা করা হয়েছে, ওপি দ্বারা প্রয়োজনীয় সমাধানটি হ'ল নকশা পরিবর্তন করা এবং যুগলভাবে দুটি অনন্য বাধা প্রয়োগ করা। বাস্কেটবল ম্যাচগুলির সাথে সাদৃশ্যটি সমস্যাটিকে খুব ব্যবহারিক উপায়ে চিত্রিত করে।
বাস্কেটবল ম্যাচের পরিবর্তে, আমি ফুটবল (বা সকার) গেমের সাথে উদাহরণ ব্যবহার করি। একটি ফুটবল খেলা (যা আমি এটি বলি Event
) দুটি দল খেলে (আমার মডেলগুলিতে একটি দল হয় Competitor
)। এটি একটি বহু থেকে বহু সম্পর্ক ( m:n
), n
এই বিশেষ ক্ষেত্রে দুটি সীমাবদ্ধ সহ , নীতিটি সীমাহীন সংখ্যার জন্য উপযুক্ত।
আমাদের মডেলগুলি দেখতে এখানে:
class Competitor(models.Model):
name = models.CharField(max_length=100)
city = models.CharField(max_length=100)
def __str__(self):
return self.name
class Event(models.Model):
title = models.CharField(max_length=200)
venue = models.CharField(max_length=100)
time = models.DateTimeField()
participants = models.ManyToManyField(Competitor)
def __str__(self):
return self.title
একটি ইভেন্ট হতে পারে:
- শিরোনাম: কারাবাও কাপ, চতুর্থ রাউন্ড,
- ভেন্যু: অ্যানফিল্ড
- সময়: 30. অক্টোবর 2019, 19:30 GMT
- অংশগ্রহণকারীদের:
- নাম: লিভারপুল, শহর: লিভারপুল
- নাম: আর্সেনাল, শহর: লন্ডন
এখন আমাদের প্রশ্ন থেকে সমস্যাটি সমাধান করতে হবে। জ্যাঙ্গো স্বয়ংক্রিয়ভাবে অনেকগুলি থেকে বহু সম্পর্কযুক্ত মডেলগুলির মধ্যে একটি মধ্যবর্তী টেবিল তৈরি করে, তবে আমরা একটি কাস্টম মডেল ব্যবহার করতে পারি এবং আরও ক্ষেত্রগুলি যুক্ত করতে পারি। আমি যে মডেল কল Participant
:
ক্লাস অংশগ্রহণকারী (মডেল। মডেল):
ভূমিকা = (
('এইচ', 'হোম'),
('ভি', 'দর্শনার্থী'),
)
ইভেন্ট = মডেলগুলি ore ফোরইনকি (ইভেন্ট, অন_ডিলিট = মডেল AS ক্যাসকেড)
প্রতিযোগী = মডেলগুলি ore
ভূমিকা = মডেলস.চারফিল্ড (সর্বোচ্চ_ দৈর্ঘ্য = 1, পছন্দগুলি = ROLES)
ক্লাস মেটা:
অনন্য_ একসাথে = (
('ইভেন্ট', 'ভূমিকা'),
('ইভেন্ট', 'প্রতিযোগী'),
)
Def_____ __ (স্ব):
'{} - {}'। ফর্ম্যাট (স্ব।
ManyToManyField
একটি বিকল্প আছে through
যা আমাদের অন্তর্বর্তী মডেল নির্দিষ্ট করার অনুমতি দেয়। মডেলটিতে এটি পরিবর্তন করা যাক Event
:
class Event(models.Model):
title = models.CharField(max_length=200)
venue = models.CharField(max_length=100)
time = models.DateTimeField()
participants = models.ManyToManyField(
Competitor,
related_name='events', # if we want to retrieve events for a competitor
through='Participant'
)
def __str__(self):
return self.title
অনন্য প্রতিবন্ধকতা এখন স্বয়ংক্রিয়ভাবে প্রতি ইভেন্ট প্রতিযোগীদের সংখ্যা দু'জনের মধ্যে সীমাবদ্ধ করবে (কারণ কেবলমাত্র দুটি ভূমিকা রয়েছে: হোম এবং দর্শনার্থী )।
একটি নির্দিষ্ট ইভেন্টে (ফুটবল খেলা) কেবলমাত্র একটি হোম দল এবং কেবলমাত্র একটি দর্শনার্থী দল থাকতে পারে। একটি ক্লাব ( Competitor
) হোম দল হিসাবে বা দর্শনার্থী দল হিসাবে উপস্থিত হতে পারে।
অ্যাডমিনে আমরা এখন কীভাবে এই সমস্ত জিনিস পরিচালনা করব? এটার মত:
from django.contrib import admin
from .models import Competitor, Event, Participant
class ParticipantInline(admin.StackedInline): # or admin.TabularInline
model = Participant
max_num = 2
class CompetitorAdmin(admin.ModelAdmin):
fields = ('name', 'city',)
class EventAdmin(admin.ModelAdmin):
fields = ('title', 'venue', 'time',)
inlines = [ParticipantInline]
admin.site.register(Competitor, CompetitorAdmin)
admin.site.register(Event, EventAdmin)
আমরা Participant
ইনলাইন হিসাবে যুক্ত করেছি EventAdmin
। আমরা যখন নতুন তৈরি করি তখন আমরা Event
হোম দল এবং দর্শনার্থী দলকে বেছে নিতে পারি। বিকল্পটি max_num
প্রবেশের সংখ্যা 2-এর মধ্যে সীমাবদ্ধ করে, সুতরাং ইভেন্টে আরও 2 টি দল যুক্ত করা যাবে না।
এটি কোনও ভিন্ন ব্যবহারের ক্ষেত্রে রিফ্যাক্টর করা যেতে পারে। আসুন আমাদের ঘটনা সুইমিং প্রতিযোগিতায় এবং পরিবর্তে বাড়ি এবং পরিদর্শক, আমরা রাস্তা 1 8. করতে আমরা শুধু refactor আছে বলতে দাও Participant
:
class Participant(models.Model):
ROLES = (
('L1', 'lane 1'),
('L2', 'lane 2'),
# ... L3 to L8
)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
competitor = models.ForeignKey(Competitor, on_delete=models.CASCADE)
role = models.CharField(max_length=1, choices=ROLES)
class Meta:
unique_together = (
('event', 'role'),
('event', 'competitor'),
)
def __str__(self):
return '{} - {}'.format(self.event, self.get_role_display())
এই পরিবর্তনটি সহ আমাদের এই ইভেন্টটি থাকতে পারে:
একজন সাঁতারু শুধুমাত্র একটি উত্তাপে একবার উপস্থিত হতে পারে এবং একটি লেন উত্তাপে একবারে দখল করা যায়।
আমি গিটহাবের কোডটি রেখেছি: https://github.com/cezar77/comp یتی ।
আবার সব ক্রেডিট দানি হেরেরে যায়। আমি আশা করি এই উত্তরটি পাঠকদের জন্য কিছু বাড়তি মূল্য সরবরাহ করবে।