我在django中有以下模型:
class Cast(TimeStampedModel):
user = models.ForeignKey(User, unique=True)
count = models.PositiveIntegerField(default=1)
kind = models.CharField(max_length = 7)
def __str__(self):
return(f"{self.kind} || {self.count} || {self.modified.strftime('%x')}")
但我希望'种类'字段只能采用以下值之一:向上,向下,奇怪,魅力,顶部或底部。如何在数据库中强制执行此操作,或者只能在接收数据时在视图中强制执行此操作?
答案 0 :(得分:2)
我认为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来节省数据库中的空间:在数据库中存储一个数字,在您的管理区域中,您会看到一个带有&的下拉菜单#34;人性化"选择。
kind = models.PositiveSmallIntegerField(
choices=(
(1, "Up"),
(2, "Down"),
(3, "Strange"),
(4, "Charm"),
(5, "Top"),
(6, "Bottom")
)
)
请参阅:
这是未在数据库级别强制执行(请参阅this ticket和此SO question),这意味着您仍然可以执行此操作:
>>> c = Cast.objects.first()
>>> c.kind = 70
>>> c.save()
但它在管理员中强制实施。如果您需要在较低级别强制执行,我建议您使用Noah Lc's answer。据我了解,这并非100%强制执行:您仍然可以执行不会通过模型的.save()
方法的批量更新,这意味着,执行Cast.objects.all().update(kind=70)
仍会设置70
字段中的值无效(kind
),但他的解决方案确实是一步"更低"而不是选择。您无法通过实例的.save()
方法进行模型更新。意思是,你不会被允许这样做:
>>> c=Cast.objects.first()
>>> c.kind=70
>>> c.save()
如果确实需要REAL数据库实施,则需要实际检查数据库的可能性并在cast.kind
列上添加约束。
例如,对于Postgres(可能还有大多数其他SQL版本),您可以创建一个新的迁移来执行此操作:
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%安全的(支票不依赖于Django:现在掌握在数据库引擎的手中):
>>> 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).
答案 1 :(得分:1)
在模型的保存方法中执行此操作:
<div class="wrap">
<div class="container">
<div class="half">
<div id="quarter1">
<a href=""><img class="photo" src="http://letsprattle.com/image/prattle-icon-square-white.png" class="" alt="" title=""></a>
</div>
<div id="quarter2">
<a href=""><img class="photo" src="http://yvonnemichaelides.com/wp-content/uploads/2016/01/clock2.gif" class="" alt="" title="" ></a>
</div>
</div>
<div class="half">
<div id="quarter3">
<a href=""><img class="photo" src="https://cdn.shopify.com/s/files/1/0387/1545/products/product_analysis_1024x1024.png?v=1426535435" class="" alt="" title="" ></a>
</div>
<div id="quarter4">
<a href=""><img class="photo" src="http://www.northperthcommunityhospice.org/images/icons/calendar-icon.png" class="" alt="" title="" ></a>
</div>
</div>
</div>
</div>