2017-12-31 21 views
0

내가 장고에 다음과 같은 모델이 모델을 제공 할 수있는 데이터를 제한 , 매력, 위 또는 아래. 어떻게 이것을 데이터베이스에 적용 할 수 있습니까? 아니면 데이터를 가져올 때만 뷰에서 적용 할 수 있습니까?장고 필드를

답변

0

내가 choices 어떻게해야한다고 생각? 많은 경우에서 본 적이 있지만

class Cast(TimeStampedModel): 
    user = models.ForeignKey(User, unique=True) 
    count = models.PositiveIntegerField(default=1) 
    kind = models.CharField(
     max_length=7, 
     choices=(
      ("up", "Up"), 
      ("down", "Down"), 
      ("strange", "Strange"), 
      ("charm", "Charm"), 
      ("top", "Top"), 
      ("bottom", "Bottom") 
     ) 
    ) 

는 데이터베이스의 공간을 절약하기 위해 SmallInteger으로 사용 : DB에 당신이 번호를 저장하고 관리 영역에서 당신이 아래로 감소 할거야 " 인간 친화적 인 "선택.

kind = models.PositiveSmallIntegerField(
    choices=(
     (1, "Up"), 
     (2, "Down"), 
     (3, "Strange"), 
     (4, "Charm"), 
     (5, "Top"), 
     (6, "Bottom") 
    ) 
) 

참조 : 여전히 당신을 의미

Choices in action

이것은 DB를 수준에 적용되지 않습니다 (this ticket을보고이 SO question)을 수행 할 수 있습니다

>>> c = Cast.objects.first() 
>>> c.kind = 70 
>>> c.save() 

하지만, 그것은 관리자에게 시행됩니다. 낮은 수준에서 시행해야하는 경우 Noah Lc's answer으로 가보는 것이 좋습니다. 내가 이해하는 한 100 % 적용되지는 않습니다. Cast.objects.all().update(kind=70)을 수행하면 kind 필드에 여전히 잘못된 값 (70)이 설정되므로 모델의 .save() 메소드를 거치지 않고 대량 업데이트를 수행 할 수 있습니다. 그러나 그의 해결책은, 실제로, 선택보다 "한 단계 더 낮습니다". 인스턴스의 .save() 메소드를 통해 수행되는 모델 갱신을 수행 할 수 없습니다. 이 작업을 수행 할 수 없습니다 것입니다 의미하는 것은 : 당신이 REAL 데이터베이스 집행을해야하는 경우

>>> c=Cast.objects.first() 
>>> c.kind=70 
>>> c.save() 

, 당신은 실제로 데이터베이스의 가능성을 확인하고 cast.kind 열 제약 조건을 추가해야합니다. (

from django.db import migrations 


def add_kind_constraint(apps, schema_editor): 
    table = apps.get_model('stackoverflow', 'Cast')._meta.db_table 
    schema_editor.execute("ALTER TABLE %s ADD CONSTRAINT check_cast_kind" 
          " CHECK (kind IN (1, 2, 3, 4, 5, 6))" % table) 


def remove_kind_constraint(apps, schema_editor): 
    table = apps.get_model('stackoverflow', 'Cast')._meta.db_table 
    schema_editor.execute("ALTER TABLE %s DROP CONSTRAINT check_cast_kind" % table) 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('stackoverflow', '0003_auto_20171231_0526'), 
    ] 

    operations = [ 
     migrations.RunPython(add_kind_constraint, reverse_code=remove_kind_constraint) 
    ] 

그리고 그래 ... 당신은 100 % 확보 할 것 : 예를 들어

, 포스트 그레스에 대한 (그리고 아마도 다른 SQL 맛의 대부분을) 당신이 이런 짓을 새로운 마이그레이션을 만들 수 있습니다 검사는 장고에 의존하지 않습니다 : 이제는 데이터베이스 엔진을 사용하고 있습니다) :

>>> c = Cast.objects.all().update(kind=70) 
django.db.utils.IntegrityError: new row for relation "stackoverflow_cast" violates check constraint "check_cast_kind" 
DETAIL: Failing row contains (2, 1, 70, 1). 
0

는 모델의 당신의 저장 방법 내부를 수행

def save(self, *args, **kwargs): 
    mylist = ['up', 'down', 'strange', 'charm',....] 
    if slef.kind in mylist: 
     super(Foo, self).save(*args, **kwargs) 
    else: 
     raise Exception, "kind take only one of the following values: up, down, strange, charm,...." 
관련 문제