জ্যাঙ্গো মডেলটিতে ENUM নির্দিষ্টকরণ এবং ব্যবহার সম্পর্কে আমি কীভাবে যেতে পারি?
জ্যাঙ্গো মডেলটিতে ENUM নির্দিষ্টকরণ এবং ব্যবহার সম্পর্কে আমি কীভাবে যেতে পারি?
উত্তর:
থেকে জ্যাঙ্গো ডকুমেন্টেশন :
MAYBECHOICE = (
('y', 'Yes'),
('n', 'No'),
('u', 'Unknown'),
)
এবং আপনি আপনার মডেলটিতে একটি চরফিল্ড সংজ্ঞায়িত করেছেন:
married = models.CharField(max_length=1, choices=MAYBECHOICE)
আপনি যদি আপনার ডিবিতে অক্ষর রাখতে না চান তবে আপনি পূর্ণসংখ্যার ক্ষেত্রগুলির সাথেও এটি করতে পারেন।
সেক্ষেত্রে আপনার পছন্দগুলি পুনরায় লিখুন:
MAYBECHOICE = (
(0, 'Yes'),
(1, 'No'),
(2, 'Unknown'),
)
from django.db import models
class EnumField(models.Field):
"""
A field class that maps to MySQL's ENUM type.
Usage:
class Card(models.Model):
suit = EnumField(values=('Clubs', 'Diamonds', 'Spades', 'Hearts'))
c = Card()
c.suit = 'Clubs'
c.save()
"""
def __init__(self, *args, **kwargs):
self.values = kwargs.pop('values')
kwargs['choices'] = [(v, v) for v in self.values]
kwargs['default'] = self.values[0]
super(EnumField, self).__init__(*args, **kwargs)
def db_type(self):
return "enum({0})".format( ','.join("'%s'" % v for v in self.values) )
ব্যবহার choices
ENUM ডিবি টাইপ ব্যবহার করা হবে না পরামিতি; আপনি choices
চার্ফিল্ড বা ইন্টিজারফিল্ড ব্যবহার করেন কিনা তার উপর নির্ভর করে এটি কেবল একটি ভোচারার বা ইন্টিগার তৈরি করবে। সাধারণত, এটি ঠিক আছে। যদি এটি আপনার কাছে গুরুত্বপূর্ণ হয় যে ENUM টাইপটি ডাটাবেস স্তরে ব্যবহৃত হয় তবে আপনার কাছে তিনটি বিকল্প রয়েছে:
এই বিকল্পগুলির যে কোনওটির সাথে, ক্রস-ডাটাবেস বহনযোগ্যতার জন্য জড়িতদের মোকাবেলা করা আপনার দায়িত্ব হবে। বিকল্প 2-এ, আপনার অ্যালটার টেবিলটি কেবল মাইএসকিউএলে চালিত হয়েছে তা নিশ্চিত করতে আপনি ডাটাবেস-ব্যাকেন্ড-নির্দিষ্ট কাস্টম এসকিউএল ব্যবহার করতে পারেন । বিকল্প 3-তে, আপনার db_type পদ্ধতিতে ডাটাবেস ইঞ্জিনটি পরীক্ষা করে ডিবি কলামের ধরণটি এমন একটি ধরণের সেট করতে হবে যা সেই ডাটাবেজে আসলে বিদ্যমান।
আপডেট : যেহেতু মাইগ্রেশন ফ্রেমওয়ার্কটি জ্যাঙ্গো ১.7 এ যুক্ত করা হয়েছিল, উপরোক্ত 1 এবং 2 বিকল্পগুলি সম্পূর্ণ অপ্রচলিত। বিকল্প 3 সর্বদা সর্বোত্তম বিকল্প ছিল যাইহোক। বিকল্পগুলির 1/2 নতুন সংস্করণটি ব্যবহার করে একটি জটিল কাস্টম মাইগ্রেশন জড়িত SeparateDatabaseAndState
- তবে সত্যই আপনি চান বিকল্প 3।
http://www.b-list.org/weblog/2007/nov/02/handle-choice-right-way/
class Entry(models.Model):
LIVE_STATUS = 1
DRAFT_STATUS = 2
HIDDEN_STATUS = 3
STATUS_CHOICES = (
(LIVE_STATUS, 'Live'),
(DRAFT_STATUS, 'Draft'),
(HIDDEN_STATUS, 'Hidden'),
)
# ...some other fields here...
status = models.IntegerField(choices=STATUS_CHOICES, default=LIVE_STATUS)
live_entries = Entry.objects.filter(status=Entry.LIVE_STATUS)
draft_entries = Entry.objects.filter(status=Entry.DRAFT_STATUS)
if entry_object.status == Entry.LIVE_STATUS:
এটি enums বাস্তবায়নের আরেকটি দুর্দান্ত এবং সহজ উপায় যদিও এটি ডেটাবেজে সত্যই এনামগুলিকে সংরক্ষণ করে না।
তবে এটি আপনাকে 'লেবেল' রেফারেন্স দেয় যখনই আপনি জিজ্ঞাসা করছেন বা যখন আপনাকে 'মান' (যা একটি সংখ্যা হতে পারে) ব্যবহার করতে হবে শীর্ষ-উত্তরের উত্তরের বিপরীতে ডিফল্ট নির্দিষ্ট করে spec
choices
ক্ষেত্রটিতে সেট করা জাঙ্গো প্রান্তে কিছু বৈধতা আনতে অনুমতি দেবে, তবে এটি ডাটাবেসের শেষে কোনও গণিতের কোনও ফর্ম সংজ্ঞায়িত করবে না ।
অন্যরা যেমন উল্লেখ করেছে, সমাধানটি হ'ল db_type
একটি কাস্টম ক্ষেত্রে নির্দিষ্ট করা।
যদি আপনি কোনও এসকিউএল ব্যাকএন্ড ব্যবহার করেন (উদাঃ মাইএসকিউএল), আপনি এটি এর মতো করতে পারেন:
from django.db import models
class EnumField(models.Field):
def __init__(self, *args, **kwargs):
super(EnumField, self).__init__(*args, **kwargs)
assert self.choices, "Need choices for enumeration"
def db_type(self, connection):
if not all(isinstance(col, basestring) for col, _ in self.choices):
raise ValueError("MySQL ENUM values should be strings")
return "ENUM({})".format(','.join("'{}'".format(col)
for col, _ in self.choices))
class IceCreamFlavor(EnumField, models.CharField):
def __init__(self, *args, **kwargs):
flavors = [('chocolate', 'Chocolate'),
('vanilla', 'Vanilla'),
]
super(IceCreamFlavor, self).__init__(*args, choices=flavors, **kwargs)
class IceCream(models.Model):
price = models.DecimalField(max_digits=4, decimal_places=2)
flavor = IceCreamFlavor(max_length=20)
রান করুন syncdb
এবং আপনার টেবিলটি পরীক্ষা করুন যাতে এটি ENUM
সঠিকভাবে তৈরি করা হয়েছিল।
mysql> SHOW COLUMNS IN icecream;
+--------+-----------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-----------------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| price | decimal(4,2) | NO | | NULL | |
| flavor | enum('chocolate','vanilla') | NO | | NULL | |
+--------+-----------------------------+------+-----+---------+----------------+
'type "enum" does not exist LINE 1: ....tablename" ADD COLUMN "select_user" ENUM('B', ...'
।
আপনি যদি সত্যিই আপনার ডাটাবেসগুলি ENUM টাইপ ব্যবহার করতে চান তবে:
শুভকামনা!
এগুলি যুক্ত করার উপর ভিত্তি করে দুটি গিথুব প্রকল্প রয়েছে, যদিও আমি কীভাবে সেগুলি বাস্তবায়িত করছি তা আমি খতিয়ে দেখিনি:
আমি মনে করি না হয় ডিবি এনাম প্রকারগুলি ব্যবহার করুন, তবে তারা প্রথমটির জন্য কাজ করছে।
ডকুমেন্টেশন থেকে :
from django.utils.translation import gettext_lazy as _
class Student(models.Model):
class YearInSchool(models.TextChoices):
FRESHMAN = 'FR', _('Freshman')
SOPHOMORE = 'SO', _('Sophomore')
JUNIOR = 'JR', _('Junior')
SENIOR = 'SR', _('Senior')
GRADUATE = 'GR', _('Graduate')
year_in_school = models.CharField(
max_length=2,
choices=YearInSchool.choices,
default=YearInSchool.FRESHMAN,
)
এখন, সাবধান হন যে এটি একটি ডাটাবেস স্তরে পছন্দগুলি প্রয়োগ করে না এটি এটি কেবল পাইথন। আপনি যদি ডাটাবেসে সেই মানটি প্রয়োগ করতে চান তবে আপনি এটি ডাটাবেস সীমাবদ্ধতার সাথে একত্রিত করতে পারেন:
class Student(models.Model):
...
class Meta:
constraints = [
CheckConstraint(
check=Q(year_in_school__in=YearInSchool.values),
name="valid_year_in_school")
]