r4fek / django-cassandra-engine

Django Cassandra Engine - the Cassandra backend for Django
BSD 2-Clause "Simplified" License
365 stars 84 forks source link

RESTful interface #3

Closed muminoff closed 10 years ago

muminoff commented 10 years ago

Any plan for integrating with django-rest-framework or django-tastypie?

muminoff commented 10 years ago

Or what do you recommend?

r4fek commented 10 years ago

Could you give an example of such integration? I think you can use them along with this engine.

muminoff commented 10 years ago

I tried to implement it with django-rest-framework, but I couldn't get it worked as django-rest-framework seems to work with only RMDBS models.. What I wanted was to make a REST API for my CassandraDB (via cqlengine) with existing django toolkits. Metaswitch has made their crest REST server for Cassandra using Tornado. But I preferred with django-way..

r4fek commented 10 years ago

Cqlengine models are different than Django's, so I can imagine that something may not work as expected. Django-rest-framework is not only ORM-dependant and for sure works with Cqlengine. Link: http://www.django-rest-framework.org/api-guide/serializers#serializers

ptchankue commented 9 years ago

Is there a solution for this issue? I also tried using the rest framework an exception is thrown when I am trying to post values: type object 'Person' has no attribute '_meta' This is how the serializer is defined

class PersonSerializer(serializers.ModelSerializer):

class Meta:
    model = Person
    fields = ('id', ....)
jbatalle commented 9 years ago

I have the same problem... Any solution?

r4fek commented 9 years ago

I'll take a look at this after the weekend guys.

muminoff commented 9 years ago

@ptchankue @jbatalle I did some workaround for that issue. Let me share it after few hours, as I cannot access my laptop now.

ptchankue commented 9 years ago

That is nice @muminoff I will be happy to try it out soon :)

muminoff commented 9 years ago

When I used django-cassandra-engine with django-restframework my silly solution was following. I made custom serializers.Serializer for cqlengine model with custom validations. For validating models I used python objects.

I will give an example as Ticket model.

This is models.py file:

from cqlengine import columns
from cqlengine import models
from uuid import uuid1
from datetime import datetime

class Ticket(models.Model):
    __table_name__ = 'tickets'
    ticket_id = columns.TimeUUID(primary_key=True, default=uuid1())
    status = coumns.Integer(default=1, index=True)
    priority = columns.Integer(default=2, index=True)
    subject = columns.Text(required=True)
    content = columns.Text(required=True)
    created_at = columns.DateTime(default=datetime.now, index=True)

...

This is objects.py file:

class TicketObject(object):                                                                                                                                                                  
    ticket_id = "" 
    status = 0
    priority = 2
    created_at = "" 

    def __init__(self, subject, content, **attrs):
        if 'status' in attrs:
            self.status = attrs['status']
        if 'priority' in attrs:
            self.priority = attrs['priority']
        self.subject = subject
        self.content = content

This is serializers.py file:

from rest_framework import serializers
from tickets.objects import TicketObject

class TicketSerializer(serializers.Serializer):
    ticket_id = serializers.CharField(required=False, read_only=True)
    status = serializers.IntegerField(required=False)
    priority = serializers.IntegerField(required=False)
    subject = serializers.CharField()
    content = serializers.CharField()
    created_at = serializers.DateTimeField(required=False, read_only=True)

    def restore_object(self, attrs, instance=None):
        if instance is not None:
            instance.status = attrs.get('status', instance.status)
            instance.priority = attrs.get('priority', instance.priority)
            instance.subject = attrs.get('subject', instance.subject)
            instance.content = attrs.get('content', instance.content)
            return instance
        return TicketObject(**attrs)

And for getting all these worked, I followed regular tutorials from django-restframework web-site to write my own customized views.

This is small snippet of the tickets/views.py:

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework import status
from tickets.models import Ticket
from tickets.serializers import TicketSerializer
from rest_framework.response import Response

...

@api_view(['GET', 'POST'])
@permission_classes((IsAuthenticated,))
def all_tickets_collection(request):                                                                                                                                                           
    if request.method == 'GET':
        tickets = Ticket.objects.all()
        serializer = TicketSerializer(tickets, many=True)                                                                                                                                      
        return Response(serializer.data)
    elif request.method == 'POST':
        ticket = Ticket()
        serializer = TicketSerializer(data=request.DATA)
        if serializer.is_valid():
            if serializer.data['status']:
                ticket.status = serializer.data['status']
            if serializer.data['priority']:
                ticket.priority = serializer.data['priority']
            ticket.subject = serializer.data['subject']
            ticket.content = serializer.data['content']

            ticket.save()
            return Response(
                {'status': 'Ticket created.'},
                status=status.HTTP_201_CREATED
            )

...

My above copy-pasted code might not work for you as I heavily customized it for simplifying. I just wanted to explain my solution. And I am not expert in Django. I just followed simple way how to avoid this issue.

Update: Some syntax edits made.

jbatalle commented 9 years ago

Now it's working! Very useful your example. Thank you @muminoff

ptchankue commented 9 years ago

Hi guys, this is not working for me, I don't know what I am doing wrong. I still get that AttributeError 'PersonSerializer' object has no attribute 'Meta'

Can u help? Regards,

On Fri, Feb 13, 2015 at 2:20 PM, Josep Batalle notifications@github.com wrote:

Now it's working! Very useful your example. Thank you @muminoff https://github.com/muminoff

— Reply to this email directly or view it on GitHub https://github.com/r4fek/django-cassandra-engine/issues/3#issuecomment-74245717 .

jbatalle commented 9 years ago

Hi, Can you show us the url.py file? If I remember correctly, depends how you define the url file the error can continue occuring..

ptchankue commented 9 years ago

Hi Josep,

This is the line that represents my endpoint in the urls.py: url(r'^api/test$', 'myapp.views.test'), In the solution I don't understand the purpose of the restore_object method in the Serializer class. Because I also need to view and add some data from and to flat files.

On Wed, Feb 18, 2015 at 1:15 PM, Josep Batalle notifications@github.com wrote:

Hi, Can you show us the url.py file? If I remember correctly, depends how you define the url file the error can continue occuring..

— Reply to this email directly or view it on GitHub https://github.com/r4fek/django-cassandra-engine/issues/3#issuecomment-74848361 .

jbatalle commented 9 years ago

Hi, i think that the restore_object method is for old versions of django. I'm developing with django 1.7.1 and I needed to replace for update and create methods. If you want, take a look in my fork of the cqlengine-cassandra (https://github.com/jbatalle/django-cassandra-engine/tree/master/testproject). See the monitoring folder

ptchankue commented 9 years ago

Hi,

I managed to fix that issue. My mistake was to use the serializers.ModelSerializer in my serializer instead of serializers.Serializer. Thank for your help :)

Regards, Patrick

On Wed, Feb 18, 2015 at 5:34 PM, Josep Batalle notifications@github.com wrote:

Hi, i think that the restore_object method is for old versions of django. I'm developing with django 1.7.1 and I needed to replace for update and create methods. If you want, take a look in my fork of the cqlengine-cassandra ( https://github.com/jbatalle/django-cassandra-engine/tree/master/testproject). See the monitoring folder

— Reply to this email directly or view it on GitHub https://github.com/r4fek/django-cassandra-engine/issues/3#issuecomment-74884114 .