Django RabbitMQ consumer

Viewed 4420

I am building a Django application which will be contacted by multiple external applications. Django application is supposed to provide UI and populate the database with the data received from external applications.

First idea was to use django_rest_framework but this seemed like creating a tightly coupled system because every external app will have to contact the Django app via REST call.

My other idea is best described with a picture: http://imgur.com/vakZvQs Several publishers would create messages on an RabbitMQ and my Django would consume those and create appropriate models in the DB.

Is something like this possible? I've used async examples from pika library for publisher and consumer and the messages are flowing as expected. Throwing Django in the mix produces errors such as:

RuntimeError: Model class django.contrib.contenttypes.models.ContentType doesn't declare an explicit app_label  

django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING_CONFIG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

Code excerpts:

# pika consumer
def on_message(self, unused_channel, basic_deliver, properties, body):
        # invoking view function
        from myapp.views import create_one_foo
        create_one_foo()
        self.acknowledge_message(basic_deliver.delivery_tag)

# views.py
from .models import Foo

def create_one_foo():
    foo = Foo()
    foo.bar = "bar"
    foo.save()
3 Answers

I had similar issues, it was solved by calling these two lines before you import the models.

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "admin.settings")
django.setup()

and then

from .models import Foo

I am still learning django, if I find a detailed explanation I will edit my answer

Use this article for creating consumer

import json
import pika
import django
from sys import path
from os import environ



path.append('/home/john/Dev/SECTION/Likes/Likes/settings.py') #Your path to settings.py file
environ.setdefault('DJANGO_SETTINGS_MODULE', 'Likes.settings') 
django.setup()
from likes.models import Quote

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost', heartbeat=600, blocked_connection_timeout=300))
channel = connection.channel()
channel.queue_declare(queue='likes')

def callback(ch, method, properties, body):
    print("Received in likes...")
    print(body)
    data = json.loads(body)
    print(data)

    if properties.content_type == 'quote_created':
        quote = Quote.objects.create(id=data['id'], title=data['title'])
        quote.save()
        print("quote created")
    elif properties.content_type == 'quote_updated':
        quote = Quote.objects.get(id=data['id'])
        quote.title = data['title']
        quote.save()
        print("quote updated")
    elif properties.content_type == 'quote_deleted':
        quote = Quote.objects.get(id=data)
        quote.delete()
        print("quote deleted")
channel.basic_consume(queue='likes', on_message_callback=callback, auto_ack=True)
print("Started Consuming...")
channel.start_consuming()

Related