尝试使用Django ContentType和GenericForeignKey创建进度应用程序

时间:2013-12-31 21:14:25

标签: django django-models django-views django-contenttypes

我有一个应用程序,我称之为Progress。我希望在我的项目中有几个不同的应用程序在发生任何事情时写入它。但是所有不同的应用程序在广播进度方面并不相同。所以我认为ContentType解决方案可行。

我遇到困难的唯一技巧是我需要在事件发生时写入Progress应用程序。比如当一个视图呈现时。我一直在尝试get_or_create,但我在查询集中获得正确的配置时遇到了问题。有关如何纠正此问题的任何建议吗?

我希望get_or_create坐在应用视图中,以便我想要的操作是写入进度的内容。

My Progress Model.py

from django.db import models
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from datetime import datetime

class Progress(models.Model):
    """
    The page log. Records the user and the object.
    """
    user = models.ForeignKey(User, related_name='user_pagelog')
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    stamp = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = (('user', 'content_type', 'stamp'),)
        verbose_name = 'View Log'
        verbose_name_plural = 'View Logs'
        get_latest_by = 'stamp'

    def __str__(self):
        return "%s got to %s on %s" % (self.user, self.content_type, self.stamp)

    @classmethod
    def get_latest_view(cls, user):
        """
        Get most recent view log value for a given user.
        """
        try:
            view_log = cls.objects.filter(user=user).order_by('-stamp')[0]
            return view_log.value
        except IndexError:
            return None

我想要写入Progress应用程序的查询集的示例:

    Progress.objects.get_or_create(user=request.user, content_type=f.id)

f = get_object_or_404(Page, publish=True)

最后,我得到的错误:

Cannot assign "1": "Progress.content_type" must be a "ContentType" instance.

我认为这意味着实例未被发现?但它存在,所以我很困惑。

感谢。

1 个答案:

答案 0 :(得分:0)

不,这根本不意味着。这意味着它所说的参数必须是ContentType模型的一个实例,而你传递的是对象本身的ID。

您可以将content_type与实际实例一起使用:

Progress.objects.get_or_create(user=request.user, content_object=f)

否则,您需要使用get_for_model()方法获取正确的ContentType,并将其与对象ID一起传递。