如何检查对象在模板中的哪个子类?

时间:2016-11-08 23:17:00

标签: python django inheritance django-templates

强制性的,我是一个django初学者,我不明白为什么我的代码不起作用。

我试图在视图中对父类进行排序以获取对象,然后将该对象传递给模板。在模板中,我为每个子类显示了某些字段,并且从父类继承了一些字段。

我尝试在我的模板中使用isinstance(),但却引发了错误。之后,我尝试向每个子类添加一个静态属性,以通过我的模板中的if语句进行检查。执行此操作时,没有子类特定字段显示。所以我尝试在视图中设置属性,但仍然没有显示任何子类特定字段。

以下是父对象类和其中一个子类(模型):

class Chunk(models.Model):
    name = models.CharField(max_length=250)
    text = models.CharField(max_length=500)
    images = models.FileField()
    question = models.CharField(max_length=250)
    expected_completion_time = models.IntegerField(default=1)
    keywords = models.CharField(max_length=250, blank=True, null=True)
    topic = models.CharField(max_length=250, blank=True, null=True)
    course = models.CharField(max_length=250, blank=True, null=True)

    def get_absolute_url(self):
        return reverse('detail', kwargs={'pk':self.pk})

    def __str__(self):
        return self.name


class Concept(Chunk):
    application = models.CharField(max_length=500)
    subconcept1 = models.CharField(max_length=500, blank=True, null=True)
    subconcept2 = models.CharField(max_length=500, blank=True, null=True)
    subconcept3 = models.CharField(max_length=500, blank=True, null=True)
    subconcept4 = models.CharField(max_length=500, blank=True, null=True)
    subconcept5 = models.CharField(max_length=500, blank=True, null=True)
    subconcept6 = models.CharField(max_length=500, blank=True, null=True)
    subconcept7 = models.CharField(max_length=500, blank=True, null=True)
    subconcept8 = models.CharField(max_length=500, blank=True, null=True)
    subconcept9 = models.CharField(max_length=500, blank=True, null=True)
    subconcept10 = models.CharField(max_length=500, blank=True, null=True)
    conceptimage = models.FileField(blank=True, null=True)

    @property
    def mode(self):
        return "concept"

以下是观点:

def startpomodoro(request):
    key = getpriority(Chunk.objects.all())
    object = Chunk.objects.get(id=key)
    a = random() > 0.5
    mode = str()
    if isinstance(object, Problem):
        if a:
            mode = "problemoutline"
        else:
            mode = "problemfull"
    elif isinstance(object, Concept):
        mode = "concept"
    elif isinstance(object, Formula):
        mode = "formula"
    elif isinstance(object, Code):
        mode = "code"

    context = dict(object=object, mode=mode)
    return render(request, 'pomodoro/pomodorogo.html', context)

以下是模板的相关部分:

            <center>

                <p>{{ object.text }}</p>

                {% if mode == concept %}

                    <p>{{ object.application }}</p>

                    <p>{{ object.subconcept1 }}</p>

                    {% if object.subconcept2 %}

                        <p>{{ object.subconcept2 }}</p>

                {% elif mode == formula %}

我不明白为什么我还没有采用这些方法。我确定这是我实施中的一个问题,但我不知道自己做错了什么。

2 个答案:

答案 0 :(得分:0)

在我正在研究的一个Django项目上,我们对继承的模型类有类似的问题。我们使用的解决方案是向父类添加一个类型。

class Chunk(models.Model):
    CONCEPT_TYPES = (
        ('Problem', 'Problem'),
        ('Concept', 'Concept'),
        ('Formula', 'Formula'),
        ('Code', 'Code'),
    )
    concept_type = models.CharField(max_length=7, choices=CONCEPT_TYPES)
    ...

然后在我们的模板中,我们会做类似的事情:

{% if object.concept_type == 'Concept' %}
   <p>{{ object.concept.application }}</p>
   <p>{{ object.concept.subconcept1 }}</p>
{% elif object.type == 'Problem' %}
    ...
{% endif %}

需要注意的是,将来我不会再像这样构建我的数据库,除非有一个非常令人信服的理由并且几乎肯定有更好的解决方案。

您还应该尝试将views.py中的if语句更改为:

if object.problem:
    ...
elif object.concept:
    ....

这可能意味着您不需要在模型中放置类型行。

答案 1 :(得分:0)

我认为您的模型中存在一些不必要的复杂情况,请尝试简化模型:

class SubConcept(models.Model):
    name = models.CharField(max_length=200)


class Chunk(models.Model):

    CHUNK_TYPES = [('P', 'Problem'),
                   ('C', 'Concept'),
                   ('I', 'Idea'),
                   ('K', 'Code'),
                   ('F', 'Formula')]
    name = models.CharField(max_length=250)
    text = models.CharField(max_length=500)
    image = models.FileField()
    question = models.CharField(max_length=250)
    expected_completion_time = models.IntegerField(default=1)
    keywords = models.CharField(max_length=250, blank=True, null=True)
    topic = models.CharField(max_length=250, blank=True, null=True)
    course = models.CharField(max_length=250, blank=True, null=True)
    chunk_type = models.CharField(max_length=1, choices=CHUNK_TYPES)
    application = models.CharField(max_length=200)
    subs = models.ManyToManyField(SubConcept, blank=True, null=True)

    def get_absolute_url(self):
        return reverse('detail', kwargs={'pk':self.pk})

    def __str__(self):
        return '{}'.format(self.name or '')

    @property
    def mode(self):
       return dict(CHUNK_TYPES)[self.chunk_type]

现在,您的观点非常简单(我忽略了getpriority方法,因为我不知道它的作用):

def pomodoro(request):
    obj = get_object_or_404(Chunk, pk=1)
    return render(request, 'foo.html', {'obj': obj})

以下是您的模板:

<center>
 <p>{{ obj.text }}</p>
 {% if obj.mode == 'Concept' %}
    <p>{{ object.application }}</p>
    {% for sub in obj.subs.all %}
        <p>{{ sub.name }}</p>
    {% endfor %}
 {% elif obj.mode == 'Formula' %}
    ...
</center>