0

I'm trying to customize this tutorial for creating click counter using Kombu and Celery in Django. The tutorial explains how to do it for url's, but what I want to do is to create a Click model, define Posts as ForeignKey field and then each time someone view that post, I'd call increment clicks for that post.

I had two problems: first one is where should I put the function call in views, since I'm using generic views (see below) ? second one is how should I work with message? Did I pass the object write to the function?

models.py

class ClickManager(models.Manager):

    def increment_clicks(self, for_url, increment_by=1):
        click, created = self.get_or_create(url=for_url, defaults={"click_count": increment_by})
        if not created:
            click.click_count += increment_by
            click.save()

        return click.click_count

class Click(models.Model):
    obj = models.ForeignKey(Post)
    click_count = models.PositiveIntegerField(_(u"click_count"), default=0)

    objects = ClickManager()

    def __unicode__(self):
        return self.obj

messaging.py

def send_increment_clicks(obj):
    connection = establish_connection()
    publisher = Publisher(connection=connection, exchange="clicks", routing_key="increment_click", exchange_type="direct")

    publisher.send(obj)

    publisher.close()
    connection.close()


def process_clicks():
    connection = establish_connection()
    consumer = Consumer(connection=connection, queue="clicks", exchange="clicks", routing_key="increment_click", exchange_type="direct")

    clicks_for_url = {}
    message_for_url = {}

    for message in consumer.iterqueue():
        obj = message.body
        clicks_for_url[obj]= clicks_for_url.get(obj, 0) + 1
        if obj in messages_for_url:
            messages_for_url[obj].append(message)
        else:
            messages_for_url[obj] = [message]

    for obj, click_count in clicks_for_url.items():
        Click.objects.increment_click(obj, click_count)
        [message.ack() for message in messages_for_url[obj]]

    consumer.close()
    connection.close()

views.py

class LinkDetailView(FormMixin, DetailView):
    models      = Post
    queryset    = Post.objects.all()

    """DON'T KNOW HOW TO PASS SELF.OBJECT TO THE FUNCTION """
    send_increment_clicks[self.object] 

    def get_success_url(self):
        ...

    def get_context_data(self, **kwargs):
        ...
sheshkovsky
  • 1,302
  • 3
  • 18
  • 41
  • 1
    Are you using Redis as your message broker perchance? Implementing a page counter using Redis is incredibly simple: http://redis.io/commands/INCR – Bobby Russell Nov 11 '15 at 22:23
  • @BobbyRussell at the moment yes, I'm using redis but I prefer not to base the counter on redis since I'd use RabbitMQ in production. – sheshkovsky Nov 12 '15 at 08:54

0 Answers0