Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
894
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Указание перечисления mySQL в модели Django
Как мне определить и использовать ENUM в модели Django?
Из документации Django :
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) )
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 db; он просто создаст VARCHAR или INTEGER, в зависимости от того, используете ли вы choices с CharField или IntegerField. В общем, это просто замечательно. Если для вас важно, чтобы тип ENUM использовался на уровне базы данных, у вас есть три варианта:
- Использовать "./manage.py sql appname " чтобы увидеть генерируемый файл SQL Django, вручную измените его, чтобы использовать тип ENUM, и запустите его самостоятельно. Если вы сначала создадите таблицу вручную,"./manage.py syncdb " не будет возиться с этим.
- Если вы не хотите делать это вручную каждый раз, когда вы создаете свой DB, поместите некоторые пользовательские SQL в appname/sql/modelname.sql, чтобы выполнить соответствующую команду ALTER TABLE.
- Создайте пользовательский тип поля и соответствующим образом определите метод db_type.
При любом из этих вариантов вы несете ответственность за последствия для переносимости данных между базами данных. В Варианте 2 вы можете использовать database-backend-specific custom SQL , чтобы гарантировать, что ваша ALTER-таблица выполняется только на MySQL. В варианте 3 Ваш метод db_type должен был бы проверить компонент database engine и установить тип столбца db для типа, который фактически существует в этой базе данных.
UPDATE: поскольку структура миграции была добавлена в Django 1.7, варианты 1 и 2 выше полностью устарели. Вариант 3 всегда был лучшим вариантом в любом случае. Новая версия options 1/2 будет включать сложную пользовательскую миграцию с использованием SeparateDatabaseAndState -- но на самом деле вы хотите Вариант 3.
http://www.b-list.org/weblog/2007/nov/02/handle-choices-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, хотя на самом деле он не сохраняет enums в базе данных.
Однако он позволяет вам ссылаться на 'label' всякий раз, когда вы задаете запрос или задаете значения по умолчанию, в отличие от ответа с самым высоким рейтингом, где вы должны использовать 'value' (который может быть числом).
Установка значения choices в поле позволит выполнить некоторую проверку на конце Django, но не будет определять какую-либо форму перечисляемого типа на конце базы данных.
Как уже упоминалось, решение состоит в том, чтобы указать db_type в пользовательском поле.
Если вы используете серверную часть SQL (например, MySQL), вы можете сделать это следующим образом:
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 | |
+--------+-----------------------------+------+-----+---------+----------------+
Если вы действительно хотите использовать свои базы данных ENUM типа:
- Используйте Django 1.x
- Распознать ваше приложение будет работать только на некоторых базах данных.
- Головоломка через эту страницу документации: http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#howto-custom-model-fields
Удачи вам!
В настоящее время существует два проекта github, основанных на добавлении этих элементов, хотя я не изучал, как именно они реализуются:
- Django-EnumField :
Предоставляет поле модели перечисления Django (с использованием IntegerField) с многократно используемым enums и проверкой перехода. - Django-EnumFields :
Этот пакет позволяет использовать real Python (pep435-style) enums с Django.
Я не думаю, что они используют DB типов перечисления, но они находятся в работе для первого из них.