我是django的新手
我想用以下逻辑创建模型:
class ExerciseCardio(models.Model): pass class ExerciseWeights(models.Model): pass class Exercise(models.Model): name = models.CharField(max_length=100, default='') EXERCISE_TYPE_CHOICES = ( (1, 'cardio'), (2, 'Weights'), ) exercise_type = models.PositiveSmallIntegerField( choices=EXERCISE_TYPE_CHOICES, default=2) if exercise_type == 1: exercise_model_type = models.ForeignKey(ExerciseCardio, on_delete=models.CASCADE, default=0) elif exercise_type == 2: exercise_model_type = models.ForeignKey(ExerciseWeights, on_delete=models.CASCADE, default=0) def __str__(self): return self.name
我知道它看起来很难看 但必须有办法做到这一点
答案 0 :(得分:1)
是的,有一种方法:你可以使用djangos generic relations。
它的要点如下:
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class Exercise(models.Model):
EXERCISE_TYPE_CHOICES = (
(1, 'cardio'),
(2, 'Weights'),
)
name = models.CharField(
max_length=100, default='')
exercise_type = models.PositiveSmallIntegerField(
choices=EXERCISE_TYPE_CHOICES, default=2)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
在您看来,在创建Exercise
实例时,您必须选择正确模型的ContentType
,可能是这样的:
obj = Exercise()
obj.exercise_type = ...
if obj.exercise_type == 1:
obj.content_type = ContentType.objects.get_for_model(ExerciseCardio)
else:
obj.content_type = ContentType.objects.get_for_model(ExerciseWeights)
答案 1 :(得分:0)
正如您所指出和Ralf所说明的那样,Django中的实际通用外键仍然很笨拙。
但是,您所谈论的是一些需要以特定方式运行的特定类型,并且我认为在django-model-utils.managers.InheritanceManager
库的自定义管理器的帮助下,这是继承的一个不错的选择。 / p>
Integer
:
models.py
示例(在Django shell中,带有我喜欢的测试应用from django.db import models
from model_utils.managers import InheritanceManager
class Exercise(models.Model):
name = models.CharField(max_length=32)
objects = InheritanceManager()
def __str__(self):
return "{n} ({t})".format(n=self.name, t=type(self))
class ExerciseCardio(Exercise):
pass
class ExerciseWeights(Exercise):
pass
):
eh