Django - 模型之间的循环关系
Django - cycle relations between models
我有两个模型设置和照片:
class Set(models.Model):
...
thumbnail = models.OneToOneField('Photo')
...
class Photo(models.Model):
...
set = models.ForeignKey('Set', related_name='photos')
...
问题是 django 无法处理这段代码,因为渲染模型 Set
需要模型 Photo
,它依赖于模型 Set
,目前尚不可用此时。这个问题的解决方案是什么?
UPD: 另一种方法,但我认为这也不是很好的解决方案。
class Set(models.Model):
...
photos = models.ManyToManyField('Photo', related_name='set')
thumbnail = models.OneToOneField('Photo')
...
class Photo(models.Model):
...
# some fields like name, size, etc..
...
无论如何,您的模型在某种程度上已经损坏,因为它没有强制执行给定集合的缩略图应该是集合照片的一部分这一事实。另一种解决方案是将其中一张照片标记为缩略图:
class Set(models.Model):
@property
def thumbnail(self):
try:
return self.photos.get(is_thumbnail=True)
except Photo.DoesNotExist:
# You can either use the first photo or just return None.
# Note that if the set has no photos self.photos.first()
# will actually return None anyway
return self.photos.first()
class Photo(models.Model):
set = models.ForeignKey(Set, related_name='photos')
is_thumbnail = models.BooleanField(default=False)
# cf https://docs.djangoproject.com/en/1.8/ref/models/instances/#validating-objects
def clean(self):
if self.is_thumbnail:
qs = self.set.photos.filter(is_thumbnail=True)
if self.pk:
qs = qs.exclude(pk=self.pk)
if qs.exists():
raise ValidationError("Only one thumbnail per set")
我有两个模型设置和照片:
class Set(models.Model):
...
thumbnail = models.OneToOneField('Photo')
...
class Photo(models.Model):
...
set = models.ForeignKey('Set', related_name='photos')
...
问题是 django 无法处理这段代码,因为渲染模型 Set
需要模型 Photo
,它依赖于模型 Set
,目前尚不可用此时。这个问题的解决方案是什么?
UPD: 另一种方法,但我认为这也不是很好的解决方案。
class Set(models.Model):
...
photos = models.ManyToManyField('Photo', related_name='set')
thumbnail = models.OneToOneField('Photo')
...
class Photo(models.Model):
...
# some fields like name, size, etc..
...
无论如何,您的模型在某种程度上已经损坏,因为它没有强制执行给定集合的缩略图应该是集合照片的一部分这一事实。另一种解决方案是将其中一张照片标记为缩略图:
class Set(models.Model):
@property
def thumbnail(self):
try:
return self.photos.get(is_thumbnail=True)
except Photo.DoesNotExist:
# You can either use the first photo or just return None.
# Note that if the set has no photos self.photos.first()
# will actually return None anyway
return self.photos.first()
class Photo(models.Model):
set = models.ForeignKey(Set, related_name='photos')
is_thumbnail = models.BooleanField(default=False)
# cf https://docs.djangoproject.com/en/1.8/ref/models/instances/#validating-objects
def clean(self):
if self.is_thumbnail:
qs = self.set.photos.filter(is_thumbnail=True)
if self.pk:
qs = qs.exclude(pk=self.pk)
if qs.exists():
raise ValidationError("Only one thumbnail per set")