Django 模型只允许多次
Django model allow only once in many
请原谅标题,但我不确定如何用文字表达。
我有一个模型“卡”和一个模型“计算机”:
class card(models.Model):
name=models.CharField(
verbose_name = 'Name',
max_length=50,
null=True,
blank=True,
)
serial=models.CharField(
verbose_name = 'Serial',
max_length=50,
null=True,
blank=True,
)
class computer(models.Model):
name=models.CharField(
verbose_name = 'Name',
max_length=50,
null=True,
blank=True,
)
slot1 = models.OneToOneField(
'card',
related_name='cardslot1',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name = 'Slot 1',
)
slot2 = models.OneToOneField(
'card',
related_name='cardslot2',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name = 'Slot 2',
)
(当然这个电脑型号是无效的)
这些卡是独一无二的,只允许在任何计算机的一个插槽中使用。实现这一目标的最佳方法是什么?我在考虑 in-between table,比如
卡片 n-1 卡片电脑 n-1 电脑
但我希望有更好的方法我现在还没有看到。
谢谢
为您的模型使用 constraints 元选项。
from django.db import models
from django.db.models import CheckConstraint, Q
class computer(models.Model)
name=models.CharField(
verbose_name = 'Name',
max_length=50,
null=True,
blank=True,
)
slot1 = models.OneToOneField(
'card',
related_name='cardslot1',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name = 'Slot 1',
)
slot2 = models.OneToOneField(
'card',
related_name='cardslot2',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name = 'Slot 2',
)
class Meta:
constraints = [
CheckConstraint(
check = ~Q(slot1=slot2),
name = 'unique_slot',
),
]
Yagus 的答案是正确的,但这里有一个纯模型替代方案。
class Card(models.Model):
name = models.CharField(
verbose_name='Name',
max_length=50,
null=True,
blank=True,
)
serial = models.CharField(
verbose_name='Serial',
max_length=50,
null=True,
blank=True,
)
class Slot(models.Model):
card = models.OneToOneField(Card,
on_delete=models.SET_NULL,
null=True,
blank=True
)
computer = models.ForeignKey('Computer',
on_delete=models.CASCADE,
related_name='slots'
)
class Computer(models.Model):
name = models.CharField(
verbose_name='Name',
max_length=50,
null=True,
blank=True,
)
这样您就可以灵活地在管理面板中为每台计算机设置 add/change 个插槽,恕我直言,这些内容比限制条件更具可读性。
由于相关名称,您仍然可以访问 Computer.slots
。
请原谅标题,但我不确定如何用文字表达。 我有一个模型“卡”和一个模型“计算机”:
class card(models.Model):
name=models.CharField(
verbose_name = 'Name',
max_length=50,
null=True,
blank=True,
)
serial=models.CharField(
verbose_name = 'Serial',
max_length=50,
null=True,
blank=True,
)
class computer(models.Model):
name=models.CharField(
verbose_name = 'Name',
max_length=50,
null=True,
blank=True,
)
slot1 = models.OneToOneField(
'card',
related_name='cardslot1',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name = 'Slot 1',
)
slot2 = models.OneToOneField(
'card',
related_name='cardslot2',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name = 'Slot 2',
)
(当然这个电脑型号是无效的) 这些卡是独一无二的,只允许在任何计算机的一个插槽中使用。实现这一目标的最佳方法是什么?我在考虑 in-between table,比如
卡片 n-1 卡片电脑 n-1 电脑
但我希望有更好的方法我现在还没有看到。 谢谢
为您的模型使用 constraints 元选项。
from django.db import models
from django.db.models import CheckConstraint, Q
class computer(models.Model)
name=models.CharField(
verbose_name = 'Name',
max_length=50,
null=True,
blank=True,
)
slot1 = models.OneToOneField(
'card',
related_name='cardslot1',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name = 'Slot 1',
)
slot2 = models.OneToOneField(
'card',
related_name='cardslot2',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name = 'Slot 2',
)
class Meta:
constraints = [
CheckConstraint(
check = ~Q(slot1=slot2),
name = 'unique_slot',
),
]
Yagus 的答案是正确的,但这里有一个纯模型替代方案。
class Card(models.Model):
name = models.CharField(
verbose_name='Name',
max_length=50,
null=True,
blank=True,
)
serial = models.CharField(
verbose_name='Serial',
max_length=50,
null=True,
blank=True,
)
class Slot(models.Model):
card = models.OneToOneField(Card,
on_delete=models.SET_NULL,
null=True,
blank=True
)
computer = models.ForeignKey('Computer',
on_delete=models.CASCADE,
related_name='slots'
)
class Computer(models.Model):
name = models.CharField(
verbose_name='Name',
max_length=50,
null=True,
blank=True,
)
这样您就可以灵活地在管理面板中为每台计算机设置 add/change 个插槽,恕我直言,这些内容比限制条件更具可读性。
由于相关名称,您仍然可以访问 Computer.slots
。