Part 1: The Basics¶
First API class¶
Idea of RPC to execute some server-side functions
from client in an easy way. In our case we will execute classes’ methods from a browser with Javascript.
Lets create some simple class in our main
application. Create main/rpc.py
with the following code:
from djangorpc import RpcRouter, Error, Msg
class MainApiClass(object):
def hello(self, username, user):
return Msg(u'Hello %s' % username)
MainApiClass
is just Python class, whose methods we are going to call with Javascript.
I hope it is clear what the hello
method going to do. As out application was inspired with ExtJs Direct,
we will call our classes actions
too. Action’s method should return Python dictionary
(with some exceptions, we will discuss this later).
request.user
is passed with arguments from a request. We do not pass request
object, because
we do not want that people use them as Django views. But it is easy tell Django RPC to pass request
if you need or do not pass request.user
if you do not need it.
Msg
and Error
are just dictionary subclasses and save a response message in msg
and error
keys respectively;
they are used to make some kind of standard in our project and you can add any extra values to these
dictionaries.
So:
return Msg(u'Hello %s' % username)
is equal to:
return {'msg': u'Hello %s' % username}
Now lets connect our action class to URL to handle requests. Add this to main/actions.py
:
router = RpcRouter({
'MainApi': MainApiClass(),
},
url_namespace='main:rpc')
And create main/urls.py
:
from django.conf.urls import patterns, include, url
from .rpc import router
urlpatterns = patterns('example.main.views',
url(r'^$', 'index', name='index'),
url(r'^rpc/', include(router.urls, 'rpc')),
)
RpcRouter
is class that helps “connect” our server-side and client-side. It generates
some Javascript to use our actions in browser, passes requests to correct action’s method and returns
its response to our callback.
Fisrt argument is dictionary mapping our action classes with names we age going to use in Javascript.
Second argument is URL-pattern namespace, that will be used to get URL with Django reverse
function, that client should use to send requests. You can see this URL-pattern in main/urls.py
.
main:rpc
is used because our application URL-pattern is added with main
namespace, and we included router.urls
with rpc
namespace.
.
In our example we will use something like this:
MainApi.hello('username')
Using Rpc¶
Lets create some simple view:
def hello(request):
return TemplateResponse(request, 'main/hello.html')
In main/hello.html
we should load generated JS code to call server-side methods:
<script src="{% url 'main:rpc:jsapi' %}"></script>
We use URL defined before in main/urls.py
.
We can call our method:
MainApi.hello('Username', function(resp, sb){
alert(resp.msg);
});
You should see alert with messages “Hellp, Username”.
Default arguments and *args¶
Action method can have optional arguments or accept *args
. Pay attention that user
is passed as
keyword argument, so you should accept **kwargs
according to Python syntax.
Lets add new method to our MainApiClass
class:
def func1(self, val, d='default', *args, **kwargs):
print 'val =', val
print 'd =', d
print 'args =', args
return Msg(u'func1')
It does nothing, just show passed arguments.
Lets execute in bowser following JS code:
MainApi.func1(1, 2, 3, 4, 5)
In Django dev-server output you can see:
val = 1
d = 2
args = (3, 4, 5)
Now execute:
MainApi.func1(1)
You will see:
val = 1
d = default
args = ()
If you execute MainApi.func1()
, you will get error “Incorrect arguments number”.
I think is clear what happens. You can play with different arguments number using our example project from repo.