I know that sessions are available through html templates like so:
<h1>{{session.name}}</h1>
That worked for a while but when I wanted to add more attributes to a user like an about text, I couldn't store everything in the session. The email and password I do store in the session because they are actually used. I can retrieve a user with the email and get the name like so:
User.query.filter_by(email=session['email']).first().name
However, when I try putting it into html like this it says that Users is undefined.
<li>Name: {{Users.query.filter_by(email=session['email']).first().name}}</li>
I guess some things like that are not carried over but is there a straightforward way to get all variables from the main.py file I was using there?
I even tried doing
return redirect(url_for('user', \
usr=Users.query.filter_by(email=session['email']).first().__dict__))
in main.py and then doing
<li class="list-group-item">Name: {{usr['name']}}</li>
but that wouldn't work either for some reason. What is going on?
The first solution I tried doesn't work because Flask doesn't have a reference to Users. The second doesn't work either because I passed it through url_for and not the actual render template function so it wouldn't know what to do with it.
My final solution would be this:
usr = Users.query.filter_by(email=session['email']).first().__dict__
return render_template('user.html', name=usr['name'], status=usr['status'],
about=usr['about'])
I could also just have passed the entire dict as before I believe.
Related
I am trying to make some tests in which asks for ads of a particular type
for instance:
http://127.0.0.1:8000/ads/?type=normal should return the normal ads
and
http://127.0.0.1:8000/ads/?type=premium should return the premium ads
the tests ask for the ads like this response = self.client.get(reverse("ads")) self.client is for the site.
Reverse() was the function i have been using for the other tests so i thought it would work as fine.
i was looking for a way i could send the parameters but there is nothing on the internet as far as i'm concerned and i have been struggling with this for hours.
┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻
If you need any more info i could bring you
i tried using:
reverse("ads", kwargs={"type": "normal"})
reverse("ads", QUERY_PARAMS={"type": "normal"})
reverse("ads", QUERY_KWARGS={"type": "normal"})
reverse("ads", {"type": "normal"})
These are all things I found online.
However, nothing worked.
When a URL is like domain/search/?q=haha, you would use request.GET.get('q', '').
q is the parameter you want, and '' is the default value if q isn't found.
However, if you are instead just configuring your URLconf**, then your captures from the regex are passed to the function as arguments (or named arguments).
Such as:
(r'^user/(?P<username>\w{0,50})/$', views.profile_page,),
Then in your views.py you would have
def profile_page(request, username):
# Rest of the method
I'm writing API using Python EVE framework.
In my on_post_GET hook I want to extend request.query_string with some additional condition for some reason.
This request.query_string looks like a raw encoded string and it's not useful to add some new condition into existing.
My string looks like:
embedded=%7B%22some_key%22%3A1%2C%22another_key%22%3A1%2C%22one_more_key%22%3A1%2C%22and_more_key%22%3A1%2C%22and_more%22%3A1%2C%22some_specific_key%22%3A1%2C%22the_last_key%22%3A1%7D&where=%7B%22some_statement%22%3A%22in%28%5B%5C%22value1%5C%22%2C%5C%22value2%5C%22%5D%29%22%7D&max_results=10&page=1&sort=%5B%28%22date%22%2C0%29%5D
So, I want to add one additional condition into WHERE statement. I may parse it somehow, but there are a few things:
1) I may have another conditions and hardcoding related to condition looks terrible for me.
2) I hope, there is some better way to extend it somehow.
Thoughts?
You should be able to make your filter by handling the lookup inside a pre_GET event hook, as in this example from pyeve's documentation:
def pre_GET(resource, request, lookup):
# only return documents that have a 'username' field.
lookup["username"] = {'$exists': True}
app = Eve()
app.on_pre_GET += pre_GET
app.run()
I am using GAE with python, and I am using many forms. Usually, my code looks something like this:
class Handler(BaseHandler):
#...
def post(self):
name = self.request.get("name")
last_name = self.request.get("last_name")
# More variables...
n = self.request.get("n")
#Do something with the variables, validations, etc.
#Add them to a dictionary
data = dict(name=name, last_name=last_name, n=n)
info = testdb.Test(**data)
info.put()
I have noticed lately that it gets too long when there are many inputs in the form (variables), so I thought maybe I could send a stringified JSON object (which can be treated as a python dictionary using json.loads). Right now it looks like this:
class Handler(BaseHandler):
#...
def post(self):
data = validate_dict(json.loads(self.request.body))
#Use a variable like this: data['last_name']
test = testdb.Test(**data)
test.put()
Which is a lot shorter. I am inclined to do things this way (and stop using self.request.get("something")), but I am worried I may be missing some disadvantage of doing this apart from the client needing javascript for it to even work. Is it OK to do this or is there something I should consider before rearranging my code?
There is absolutely nothing wrong with your short JSON-focused code variant (few web apps today bother supporting clients w/o Javascript anyway:-).
You'll just need to adapt the client-side code preparing that POST, from being just a traditional HTML form, to a JS-richer approach, of course. But, I'm pretty sure you're aware of that -- just spelling it out!-)
BTW, there is nothing here that's App Engine - specific: the same considerations would apply no matter how you chose to deploy your server.
I have a question about Django and it's routing system. I believe that it can be powerfull, but right now I am struggling with one issue I don't experience when working in other frameworks and I can't seem to get a grip on it. Worth to mention that I don't have much experience with Django at this point.
The issue is simple - I have a view which takes two optional parameters, defined like this
def test_view(id=None, grid=None):
Both parameters are optional and frequently are not passed. Id can only be an integer and grid will never be an integer (it is a special string to control datagrid when I don't want to use sessions). I have a route defined like this:
url(a(r'^test_view (\/(?P<id>\d+))? (\/(?P<grid>[^\/]+))? \/?$'), views.test_view, name='test_view'),
This works great and I am not having trouble with using one-way routes. But when I try to use the reverse function or url template tag, following error occurs:
Reverse for 'test_view' with arguments '('20~id~desc~1',)' and keyword arguments '{}' not found.
In this example I tried to find reverse without the id, just with the grid parameter. I have tried various methods of passing parameters to the reverse function:
(grid, )
(None, grid)
('', grid)
{id=None, grid=grid}
All of them result in same error or similliar one.
Is there a way to implement this in django? Maybe just disable the cool URL for the grid parameter. That is how I do it in for example Nette framework for PHP, isntead of having an url like this: 'localhost/test_view/1/20~id~desc~1' I have url like this: 'localhost/test_view/1?grid=20~id~desc~1'. This would be completely sufficient, but I have no idea how to achive this in Django.
As you note in your question, the best way to achieve this is to use standard GET query parameters, rather than doing it in the path itself. In Django you do that exclusively in the view; the URL itself is then just
url(r'^test_view$', views.test_view, name='test_view'),
and you request it via localhost/test_view?id=1&grid=20~id~desc~1. You get the params from request.GET, which is a dictionary-like object; you can use .get so that it does not raise a KeyError when the key is not provided.
def test_view(request):
id = request.GET.get('id')
grid = request.GET.get('grid')
I'm currently moving a project from Pylons 1.0 to Pyramid.
My problem so far is how to use restful routes in Pyramid. I'm currently using pyramid_handlers since it seemed like a good start. I'm using Akhet.
So here is the two important lines in my route:
config.add_handler("new_account", "/accounts/new", "sproci2.handlers.accounts:Accounts")
# or
config.add_handler("new_account", "/accounts/new", "sproci2.handlers.accounts:Accounts", action="new")
My action:
#action(name="new_account", renderer='accounts/new.mako', request_method='GET')
The errors:
TypeError: 'Accounts' object is not callable
or
ValueError: Could not convert view return value "{}" into a response Object.
Accounts... so far so good, it is easy to understand that pyramid_handlers doesn't seem to register normally or handle name as it should... that said in request.matched_route, I do have "new_account".
If I add "action='new'" in the route definition, it will find the function but it will not listen to the action definition. In other words, it will fail to find a renderer and expect a response object. The request_method parameter doesn't actually do anything yet, so removing it doesn't change any results.
In short, the #action(name="..." doesn't work. Pyramid fails to find the function by itself and if the function name is defined it fails to execute the action statement.
No idea what I'm doing wrong.
Correct way to do it.
config.add_handler("new_account", "/accounts/new", "sproci2.handlers.accounts:Accounts", action="new_account")
EDIT
route_name is probably going to get used by url generator functions. While action is the actual name in #action. As I understood, #action name was the route_name and not the action name. That makes more sense now.
Well a call to add_handler needs an action pattern. So that's either adding {action} to the url pattern, or setting action= as an argument. Those actions must match the names defined in #action decorators. In your example, you named the action new_account, yet you called add_handler with an action of new. Thus they aren't properly connected.