AttributeError: 'Bottle' object has no attribute 'template' - mongodb

Example One
Consider the following:
import bottle
import pymongo
application = bottle.Bottle()
#application.route('/')
def index():
cursor = [ mongodb query here ]
return application.template('page1',{'dbresult':cursor['content']})
Assume that the MongoDB query is correct, and the application is calling the content value of cursor correctly and passing it to the template which is formatted correctly.
The errors I am getting in the logs are to do with being able to use the template() method eg:
AttributeError: 'Bottle' object has no attribute 'template'
Example Two
If I change the corresponding assignment and call to:
application = bottle
application.template
The error is:
TypeError: 'module' object is not callable
Example Three
If I change the corresponding assignment and call to:
application = bottle
#application.route('/')
#application.view('page1.tpl')
return {'dbresult':cursor['content']}
The error is:
TypeError: 'module' object is not callable
Question
What is the correct call to the template() method to use to get Example One working?

To get "Example One" working:
return bottle.template('page1',{'dbresult':cursor['content']})
template() is in the bottle module; just reference it as bottle.template(...).

bottle.template() isn't a method of the bottle.Bottle() application object. It's a function in the bottle module.

Related

Symfony Form - Value Object, DataMappers and EventSubscriber

I am having trouble to dynamically modify field in my form using DataMapper and EventSubscriber.
Here is my form:
A select field
A field which will be modified by the select field above.
I am using an EventSubscriber to dynamically modify my form using AJAX.
And a DataMapper to map my Value Object to the form and vice-versa.
So when i do that:
$moneyForm = $this->createForm(MoneyType::class);
Everything is working. But when i pass my Value Object as data class:
$money = new Money(199, 'USD');
$moneyForm = $this->createForm(MoneyType::class, $money);
I got an error here:
public function mapDataToForms($viewData, $forms)
{
$forms = iterator_to_array($forms);
$forms['money']->setData($viewData ? $viewData->money() : 0);
$forms['currency']->setData($viewData ? $viewData->currency() : 'USD');
}
This error says that: Notice: Undefined index:.
It seems like the form has been replaced by a new one and i don't understand it.
I don't know why when i use a data mapper alone, or event subscriber alone everything is working.
But when i try to mix, both of them i got this error.
Does anyone have a clue of what's going on here?
Thank you

How to call save method in mongoengine.EmbeddedDocument class

import mongoengine
class Model1(mongoengine.DynamicDocument):
name = mongoengine.StringField()
addr = mongoengine.EmbeddedDocumentField(Model2)
class Model2(mongoengine.EmbeddedDocument):
loc = mongoengine.StringField()
# do some stuff
def save(self, *args, **kwargs):
print "test line print...."
super(Model2, self).save(*args, **kwargs)
now when I save Model1 instance. it doesn't call save method
m2 = Model2(loc='some text')
m1 = Model1(name='name')
m1.addr = m2
m1.save()
if I try to explicity call the save method on Model2, it complains that NoneType object has no attr save
m2 (embedded doc) does have a save method. It calls m1.save(). See the code.
The assumption calling m1.save() will call save() on all embedded documents is false. (I fell in the same trap...)
So unfortunately, you can't safely override an embedded document's save method expecting it to be called each time the document is saved.
But you can add it a pre_save method you call from m1.save() (or in a callback catching the pre_save signal in the document).
However, calling m2.save() should call m1.save() and save the whole document. I can't explain this error: NoneType object has no attr save. You should edit your question to provide the full traceback.

Playframework Scala Async controller for JSON request

I am trying to write an async PlayFramework controller that receives a POST request and creates a new object in the database:
def register = Action(BodyParsers.parse.json) { request =>
val businessInfoResult = request.body.validate[BusinessInfo]
businessInfoResult.fold(errors =>{
BadRequest(Json.obj("status"-> "Error", "message"->JsError.toJson(errors))) //Error on this line
}, businessInfo=> {
//save the object
Ok(Json.obj("status" ->"OK", "message" -> ("Place '"+ businessInfo.businessName +"' saved.") )) //Error on this line
})
}
However, it keeps throwing the error below:
reference to Json is ambiguous; it is imported twice in the same scope by import play.libs.Json and import play.mvc.BodyParser.Json AsyncController.scala
The errors are thrown at line 108 and 105 which correspond to lines commented with //Error on this line above (lines with BadRequest(..) and Ok(..))
How do I fix this issue? I can using new JsValue(Map(..)) but was wondering if there's any other way.
Thank you so much for your help.
Rather than Json, you probably want to call play.libs.Json. The problem here is that, considering the imports in your file, you have two objects / classes called Json and the compiler can't choose which one it should use. Calling play.libs.Json, you'll give the compiler enough information.
You could use one or more aliases in your imports:
import play.libs.Json
import play.mvc.BodyParser.{Json => JsonParser}
JsonParser is just an example. You can use anything you like as long as it's unique within the file.
Instead of writing Json (for play.mvc.BodyParser.Json) you could now use the alias JsonParser.
But are you sure you even need to import play.mvc.BodyParser.Json? Because you don't seem to use it.

Yii RBAC make Users update profile by himself

I'm trying to do this with mongodbauthmanager. I'm follow step by step in Usage section but finally i'm getting PHP warning: Illegal offset type. I had posted this question at Yii Extension before clone to SO:
Please tell me what is wrong?
1// Config
'authManager'=>array(
'class' =>'CMongoDbAuthManager',
'showErrors' => true,
),
2// Create auth items in db
$auth = new CMongoDbAuthManager();
$bizRule = 'return Yii::app()->user->id==$params["User"]->_id;';
$auth->createTask('updateSelf', 'update own information', $bizRule);
//I had tried with $auth->createOperation() but they has the same error
$role = $auth->createRole('user');
$role->addChild('updateSelf');
$auth->save();
and here is result in db
result in db http://i.minus.com/iIpXoBlDxaEfo.png
**3// Checking access in controller ** - UPDATE CODE AND ERROR
public function actionUpdate($id)
{
$model=$this->loadModel($id);
$params = array('User'=>$model);
if (!Yii::app()->user->checkAccess('updateSelf', Yii::app()->user->id,$params) )
{
throw new CHttpException(403, 'You are not authorized to perform this action');
}
//another statement ...
}
4// Getting error:
Fatal error : Cannot use object of type MongoId as array in F:\Data\03. Lab\www\yii\framework\web\auth\CAuthManager.php(150) : eval()'d code on line 1
RESOLVED PROBLEM
Base-on the answer of #Willem Renzema, I resolve my problem. Now, I update here and hope it useful for someone have this error.
0// First, config authManager with defaultRoles
'authManager'=>array(
'class'=>'CMongoDbAuthManager',
'showErrors' => true,
'defaultRoles'=> array('user'),//important, this line help we don't need assign role for every user manually
),
1// Fix save id in UserIdentity class
class UserIdentity extends CUserIdentity
{
private $_id;
//...
public function authenticate()
{
//...
$this->_id = (string)$user->_id;//force $this save _id by string, not MongoId object
//...
}
//...
}
2// Fix $bizrule in authe items
($bizrule will run by eval() in checkAccess)
//use _id as string, not MongoId object
$bizRule = 'return Yii::app()->user->id==(string)$params["User"]->_id;';
3// And user checkAccess to authorization
public function actionUpdate($id){
/**
* #var User $model
*/
$model=$this->loadModel($id);
$params = array('User'=>$model);
if (!Yii::app()->user->checkAccess('updateSelf', $params) )
{
throw new CHttpException(403, 'You are not authorized to perform this action');
}
//...
}
4// Done, now we can use checkAccess :D
First off, your original use of checkAccess was correct. Using Yii::app()->user->checkAccess() you are using the following definition:
http://www.yiiframework.com/doc/api/1.1/CWebUser#checkAccess-detail
Now, CWebUser's implementation of checkAccess calls CPHPAuthManager's implementation, which is where you encountered your problem with an illegal offset type.
http://www.yiiframework.com/doc/api/1.1/CPhpAuthManager#checkAccess-detail
An Illegal offset type means you are attempting to access an array element by specifying its key (also known as: offset) with a value that doesn't work as a key. This could be another array, an object, null, or possibly something else.
Your stack trace posted on the extensions page reveals that the following line gives the problem:
if(isset($this->_assignments[$userId][$itemName]))
So we have two possibilities for the illegal offset: $userId and $itemName.
Since $itemName is clearly a string, the problem must be with $userId.
(As a side note, the fact that your stack trace revealed surrounding code of this error also revealed that, at least for CPHPAuthManager, you are using a version of Yii that is prior to 1.1.11. Observe that lines 73 and 74 of https://github.com/yiisoft/yii/blob/1.1.11/framework/web/auth/CPhpAuthManager.php do not exist in your file's code.)
At this point I would have guessed that the problem is that the specified user is not logged in, and so Yii::app()->user->id is returning null. However, the new error you encountered when placing Yii::app()->user->id as the 2nd parameter of checkAccess reveals something else.
Since the 2nd parameter is in fact what should be the $params array that appears in your bizRule. Based on the error message, this means that Yii::app()->user->id is returning a mondoId type object.
I was unfamiliar with this type of object, so looked it up:
http://php.net/manual/en/class.mongoid.php
Long story short, you need to force Yii::app()->user->id to return the string value equivalent of this mondoId object. This likely set in your UserIdentity class in the components folder. To force it to be a string, simply place (string) to force a type conversion.
Example:
$this->_id = (string)$User->_id;
Your exact code will vary, based on what is in your UserIdentity class.
Then, restore your checkAccess to the signature you had before, and it should eliminate the Illegal offset error you encountered originally.
Note however that I have not used this extension, and while performing the following actions should fix this issue, it may cause new issues if the extension relies on the fact that Yii::app()->user->id is a mondoId object, and not a string.

How to get rid of the __actions__ entry in the CrudRestController's response?

I'm subclassing the CrudRestController to implement an REST interface. It works fine, but the response dict contains an __actions__ entry which contains some html code that I really don't want in my response.
According to the TableFiller class' docstring something like this should work:
class ProcessController(CrudRestController):
model = Process
#...
class table_filler_type(TableFiller):
__model__ = Process
__actions__ = False
But the page always throws an AttributeError: 'Process' object has no attribute '__actions__'
Any advice?
Despite the inline docs, the correct way seems to be:
class table_filler_type(TableFiller):
__model__ = Process
__omit_fields__ = ['__actions__', ]