I am developing a template/page for Odoo where I am using an RPC call.
The problem I am having is that I want the page to be of type public, but unfortunately RPC calls are only available for authenticated users. I am trying to execute a search query, e.g:
rpc.query({
model: modelName,
method: 'search_read',
args: [domain, fields]
})
You shold write a controller auth='public' and call it with any REST Client.
Controller somthin like this:
#http.route('/my_controller', type='json', method=['GET,POST'], auth='public', csrf=False)
def my_controller(self):
...
You only should be careful with passing the proper cokie for Odoo.
I hope this answer can be helpful for you.
Related
I want to consume data from a GraphQL API.
how can I achieve that? I am new to webapi and any help is appreciated
Assuming the API you want to consume uses HTTP, you should be able to use cUrl, wget, Charles, Postman or even just the URL bar in a browser to make a request.
To write your first query, you can start with the following:
query theNameOfMyQuery {
}
Now that you have a named query, you can start populating it with whatever fields your GraphQL server is exposing. For a blog example, you might have something like this:
query theNameOfMyQuery {
posts {
title
author
}
}
Now, to turn that into something you can request, all you need to do is URL encode it and add it to your URL. A typical URL looks like this:
https://www.someserver.com/?query=...&variables=...
So for the above example, you would have the above query
https://www.someserver.com/?query=query%20theNameOfMyQuery%20%7B%0D%0A%20%20posts%20%7B%0D%0A%20%20%20%20title%0D%0A%20%20%20%20author%0D%0A%20%20%7D%0D%0A%7D
Some Resources:
Evolution of API Design - this video explains some of the concepts of GraphQL and why it exists.
howtographql.com - This is an amazing set of tutorials for every implementation you could imagine
I have the following model:
class LibraryBook(models.Model):
_name = 'library.book'
name = fields.Char('Title', required=True)
date_release = fields.Date("Release Date")
author_ids = fields.Many2many("res.partner", string="Authors")
I'm new to Odoo and trying to understand the basics of how to save data to my model from a POST request like the following
curl -i -X POST --data "name=Odoo%20-%20Much%20Mystery,%20Wow&author_id=Doge" http://0.0.0.0:8069/test
I found a way doing this by setting the csrf parameter in my controller to false like so:
[...]
#http.route('/test', type='http', auth='public',methods=['POST'], website=True, csrf=False)
def test(self, **kwargs):
record = request.env['library.book'].sudo()
record.create(kwargs)
I'm wondering now if there is a way to avoid setting csrf=false since I've read that it's a bad idea to do so in general. Also, what would I need to get rid of that .sudo()? Not setting csrf=false leads to a 400 BAD REQUEST with Invalid CSRF token. Removing sudo() leads to a 500 INTERNAL SERVER ERROR. In Odoo Development Cookbook it says in one example with auth='none'
Lack of a user is also why we have to sudo() all our calls to model methods in the example code
Assuming I would expect a POST request from an API, is it possible to associate it with a user so I don't have to sudo()?
I would very much appreciate any clarification on this.
UPDATE
So I just found this (line 817):
if the form is accessed by an external third party (e.g. REST API endpoint, payment gateway callback) you will need to disable CSRF
protection (and implement your own protection if necessary) by
passing the csrf=False parameter to the route decorator.
which I guess leaves only one question open, regarding sudo.
SUDO()
creates a new environment with the provided user set, uses the administrator if none is provided (to bypass access rights/rules in safe contexts), returns a copy of the recordset it is called on using the new environment:
Odoo does not allow public users to create, update, delete a record.
If we want to create a record from the public users then we need to create a record with the sudo().
Create record object as administrator
request.env['library.book'].sudo().create(vals)
I hope this may help you.
for more information you can navigate to following links :
https://www.odoo.com/documentation/9.0/reference/orm.html
Thanks
In Parse there is something called:
Parse.Cloud.beforeSave
I wonder if there is something to play the role of a:
Parse.Cloud.beforeRead
I need a way to control what is going to be returned to the user when a request is made to the DB.
In particular in certain circomstances, depending on information on the server, I want to force blank fields in the result of the DB request made by the user. Any standard way to do this?
There is no Parse.Cloud.beforeRead kind of function supported by Parse.
Instead, you can define a custom cloud function using
Parse.Cloud.define('readObjects', function(request, response) {...} );
that returns array of objects. This function will act as a wrapper over the Parse query.
Then, your client apps should be calling this cloud function to fetch objects rather than direct Parse.Query requests.
Let's say I have an action:
def result = Action { Ok(views.html.home.result()) }
From result view I want to send ajax requests to the server. What's the standard (if any) way to name the actions that receive such the ajax requests? It might be something like:
def getResultAjax(param1: Int) = //....
To my mind, it look clumsy.
Your ideas?
There's no such convention in Play, anyway action's name should rather contain info about returned data i.e. listOfBooks then just getResult.
On the other hand when there's a lot of different methods (some common, other for ajax requests) it can be cleaner if you'll use ajaxListOfBooks or create BooksAjax controller to handle AJAX request only.
BTW: Purists would say that the requests REST's HTTP methods should also be taken into account, and then action names can be simplified, pseudo routes:
GET /ajax/books Books.list
GET /ajax/books/:id Books.get(id)
PUT /ajax/books Books.create
POST /ajax/books/:id Books.update(id)
If i have a link like this one Get User Data who points in a view inside my own server, is there any way to send a json object (maybe just maybe with ajax?) to another external server and retrieve an answer? Something like this:
from django.shortcuts import render
def profile(request):
#send a json object to another server like http://www.myotherserver.com/user
#get the answer and process it
return render(request, 'accounts/profile.html' ,
{'profile_user': data_from_the_external_server})
The above i can implement it of course with jquery-ajax but i just was wondering if i can do it this way...
Thanks in advance.
Of course you can. Why wouldn't it be possible?
Don't code this in AJAX if that's not necessary.
There are 2 things you need, you need to prepare the JSon to send and then you need to send it to the API you want:
Look at "simplejson" to create the json data to send.
Look at "urllib" to send a request to another server in Python (like here: How to send a POST request using django?)
Also do not put it straight in your view. Create a new class for it. So in your view you'll have something like that:
def profile(request):
# instantiate your service here (better with DI)
profile_user = my_service.get_profile_user()
return render(
request,
'accounts/profile.html' ,
{
'profile_user': profile_user
}
)
If you need to send HTTP data (via a POST or GET) to another server and receive a result from within your view, you can use Python's urllib2 library. However there is an easier third party library called Requests which can handle this task for you.