Question

I have an app that I'm calling Progress. I want to have several different apps throughout my project write to it whenever something happens. But all the different apps are not the same in how they broadcast progress. So I thought that a ContentType solution would work.

The only trick that I'm having a hard time figuring out is that I need to write to the Progress app when an event occurs. Such as when a view renders. I've been trying get_or_create but I'm having trouble getting the right configuration in the queryset. Any suggestions for how to correct this?

I want the get_or_create to sit in the view of an app so that the action I want is what writes to the progress.

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

An example of the queryset that I want to write to the Progress app:

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

Where f = get_object_or_404(Page, publish=True)

Finally, the error I'm getting:

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

Which I think it means the instance isn't getting found? But it exists, so I'm confused.

Thanks.

Was it helpful?

Solution

No, it doesn't mean that at all. It means what it says, that the parameter has to be an instance of the ContentType model, whereas you're passing the ID of the object itself.

You might be able to use content_type along with the actual instance:

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

Otherwise you'll need to get the right ContentType using the get_for_model() method, and pass that along with the object id.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top