Django modelinde mySQL enum belirtme

oy
81

Nasıl belirterek ve Django modelinde bir enum kullanma hakkında gidiyorsun?

Oluştur 21/08/2008 saat 22:48
kaynak kullanıcı
Diğer dillerde...                            


9 cevaplar

oy
95

Gönderen Django belgeleri :

MAYBECHOICE = (
    ('y', 'Yes'),
    ('n', 'No'),
    ('u', 'Unknown'),
)

Ve siz modelinde bir Charfield tanımlayın:

married = models.CharField(max_length=1, choices=MAYBECHOICE)

Eğer db harfleri sahip olmak ister etmezseniz tamsayı alanları ile de yapabilirsiniz.

Bu durumda, seçimlerinizi yeniden yazın:

MAYBECHOICE = (
    (0, 'Yes'),
    (1, 'No'),
    (2, 'Unknown'),
)
Cevap 21/08/2008 saat 22:54
kaynak kullanıcı

oy
29

Kullanımı choicesENUM db türünü kullanmaz parametreyi; Sadece kullandığınız bağlı olarak bir VARCHAR veya INTEGER yaratacak choicesbir Charfield veya IntegerField ile. Genellikle, bu sadece iyi. O ENUM tipi veritabanı seviyesinde kullanıldığını sizin için önemli ise, üç seçenek vardır:

  1. ENUM türü kullanmak değiştirmek elle SQL Django üretir görmek için "./manage.py sql APPNAME" kullanın ve kendiniz çalıştırın. Onunla ilk tabloyu manuel oluşturursanız, "./manage.py syncdb" olmaz karmaşa.
  2. el Eğer DB oluşturmak her zaman bunu yapmak istemiyorsanız, uygun ALTER tablo komutu gerçekleştirmek için appname / sql / modelname.sql bazı özel SQL koydu.
  3. Bir oluşturma özel alan tipi ve uygun db_type yöntemi tanımlar.

Bu seçeneklerden herhangi sayesinde, veritabanları arası taşınabilirlik için etkileri ile başa çıkmak için sizin sorumluluğunuz olacaktır. Seçeneğinde 2'de şunu kullanabilirsiniz veritabanı arka uç özgü özel SQL sizin ALTER tablo sadece MySQL üzerinde çalıştırılır sağlamak. Seçeneğinde 3'te senin db_type yöntemi veritabanı motorunu kontrol etmek ve aslında bu veritabanında var olan bir türe db sütun türünü ayarlamak gerekir.

UPDATE : taşıma çerçevesi Django'ya 1.7 ilave edildi için, seçenek 1 ve 2, yukarıda tamamen geçersizdir. Seçenek 3 en iyi seçenek zaten hep oldu. Seçeneklerin 1/2 yeni sürümü kullanan karmaşık özel bir göç yer alacağı SeparateDatabaseAndState- ama gerçekten seçeneği 3 istiyorum.

Cevap 29/08/2008 saat 02:57
kaynak kullanıcı

oy
6

Gerçekten veritabanları ENUM türü kullanmak isterseniz:

  1. Django 1.x kullanın
  2. sadece bazı veritabanları üzerinde çalışacak Başvurunuzu tanıdınız.
  3. Bu dokümantasyon sayfasından Bulmaca: http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#howto-custom-model-fields

İyi şanslar!

Cevap 02/12/2008 saat 17:21
kaynak kullanıcı

oy
35
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) )
Cevap 07/10/2009 saat 09:47
kaynak kullanıcı

oy
8

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:

Bu gerçekten veritabanında Çeteleler kaydetmez rağmen çeteleler uygulamanın başka güzel ve kolay bir yoludur.

Ancak sorgulama veya (bir sayı olabilir) 'değerini' kullanmak zorunda en çok oy alan cevap karşıt olarak varsayılan belirterek ne zaman 'Etiketi' başvurmak için izin vermez.

Cevap 26/10/2012 saat 14:03
kaynak kullanıcı

oy
9

Ayar choicessahada Django ucunda bazı doğrulama sağlayacak, ancak olmayacak veritabanı ucunda bir sabit tür herhangi bir biçimde tanımlar.

Diğerleri de söylediğim gibi, çözüm belirtmektir db_typeÖzel bir alana göre.

Bir SQL arka uç (örneğin MySQL) kullanıyorsanız, bunu böyle yapabilirsiniz:

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)

Run syncdbve bu görmek için tablonuzu incelemek ENUMdüzgün oluşturuldu.

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    |                |
+--------+-----------------------------+------+-----+---------+----------------+
Cevap 26/09/2013 saat 22:38
kaynak kullanıcı

oy
-2

Eğer ithalat yapmak sonra models.py dosyasının üst, bu satırı ekleyin:

    enum = lambda *l: [(s,_(s)) for s in l]
Cevap 03/03/2014 saat 17:18
kaynak kullanıcı

oy
3

Ben tam olarak hayata nasıl olduğunu baktım yok gerçi, bu ekleme dayalı iki github proje Şu anda konum:

  1. Django EnumField :
    yeniden enums ve geçiş doğrulama (IntegerField kullanarak) bir numaralandırma Django modeli alan sağlar.
  2. Django-EnumFields :
    Bu paket Django ile gerçek Python (PEP435 tarzı) Çeteleler kullanmanızı sağlar.

Bence ya DB enum türlerini kullanmak, ancak bunlar yok eserlerinde ilk biri için.

Cevap 09/02/2015 saat 09:23
kaynak kullanıcı

oy
0

Django 3.0 yerleşik destek numaralamalar için

Gönderen belgeler :

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,
    )

Şimdi, unutmayın bu bir veritabanı düzeyinde seçimler zorlamaz bu Python sadece yapısıdır. Ayrıca veritabanına bu değeri zorlamak istiyorsanız veritabanı kısıtlamaları ile birleştiren olabilir:

class Student(models.Model):
    ...

    class Meta:
        constraints = [
            CheckConstraint(
                check=Q(year_in_school__in=YearInSchool.values),
                name="valid_year_in_school")
        ]
Cevap 22/09/2019 saat 20:08
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more