I have a Django view that I want to render in a new window when it is called from a python script outside of views.py. My questions are 1.Can I use a Django view from a python script in a subdirectory of my project that is outside the app where the view is located (view location: MyProject/Myapp/views.py and the python script location: MyProject/ProcessingCode/myscript.py)? 2. If that is possible, how do I render the view in a new window?
Django view that I want rendered in a new window:
def Error_Popup_Page(request,message):
context = {'message':message}
return render(request,'InterfaceApp/Error_Notification.html',context)
How it will be used:
def SomeOtherPythonFunction():
try:
#data processing code
except Exception as e:
return Error_Popup_Page(request,'error message')
You're trying to trigger a change on the user browser from on an event that happens on your server. This is impossible to do with Django alone, since Django job is only to respond user requests.
This is where Django is placed in the request chain:
User browser (click on href or ajax event) --> Your server --> Django
--> User browser (gets response and display to the user)
As you can see, there is no way for Django to trigger any event on the user end without the user calling it.
What you're trying to do can be achieved with an async task: in other words, you have to open a websocket and connect the user browser to it with JavaScript.
There are many frameworks for doing this, Celery being the most used in conjuction with Django.
nodejs is also widely used but integrating it with Django is more complex.
Related
I'm trying to add a Flask-JWT-Extended specific error handler to Flask-Restx. In particular, I'm trying to add #jwt.expired_token_loader. I need to display templates to users in my API and for that I need to save the users information in their browser.
#jwt.expired_token_loader
#jwt_required(refresh=True)
def refresh_cookie_handler(jwt_header, jwt_payload):
return render_template("/refresh_cookie/index.html")
When the cookie/ token is expired, it just does nothing. The handler works on the normal Flask routes, like app.route().
I'm using Django admin and I'm looking for showing a message to user while my page is loading (something like: please wait...). Is there a way to show this temporary message if the user clicked 'admin:appname_modelname_changelist' link (load an object to change).
I'm not using ajax to transfer the request.
I'm looking for something like ajaxStart and ajaxComplete functions in order to control start/end loading page.
You could override the admin template and add a Javascript onClick handler on the link to show a loader (with jQuery for example).
Overriding admin templates:
https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#overriding-admin-templates
jQuery onClick handler:
https://api.jquery.com/click/
I am currently using code found here:
http://flask.pocoo.org/snippets/8/
And I decorate my function accordingly to have the admin authenticate when requesting a specific admin page. However, instead of requiring the admin to keep authenticating each time they admin page, I noticed that it somehow keeps track of the session and no longer requires authentication after successfully authenticating once. Is there some way to force flask to re-authenticate every time an admin requests the given decorated admin page?
Using the included snippet, there is no good way to force a user to log in every time they request the given page.
This is because that snippet is using HTTP Basic Auth and there is no good way to ask the browser to stop sending that header.
What you are looking for can be done with a custom decorator. You can use the sample below. Note that your case will be different, but you can use this as a guide.
from web import app, has_role
#app.route("/admin/my_page")
#login_required
#has_role(role="admin")
def admin_my_page():
//do stuff
Then, in your project init, or an include file you can add the following:
def has_role(role=None):
def _initial_decorator(view_func):
def _decorator(*args, **kwargs):
response = view_func(*args, **kwargs)
if g.user.user_level != role:
from flask import redirect, url_for
return redirect(url_for("no_access"))
return response
return wraps(view_func)(_decorator)
return _initial_decorator
This should at lease give you an idea of how to create a custom decorator, and then check for role permissions. You can expand this to however you need. You can put engine logic, or other checks to fit your project.
I'm trying to integrate Mozilla Persona (browserid) into a Pyramid application. The login process is:
user can login on any page by clicking on the login button
a popup then shows a login form
when the users enters correct login/password, an ajax call is made by the popup to a Pyramid view that checks users credentials, and calls Pyramid remember function if the check succeeded
the browserid javascript code then reloads the current page
Now I want to handle the case of a new user subscribing to the web app and present a new view asking for a few more details (desired username, etc).
Since the "remember" function is called by an ajax call from the popup, I cannot redirect the user the the "/newuser" page.
So every view needs to redirect new users to the "/newuser" url whenever the remembered browserid has no corresponding user in the database.
Is there a way to intercept user requests before calling a view to call the "new_user" view instead? Or maybe my authentication approach is fundamentally incorrect and I should rely on another approach?
One way to do this would be to create an exception that should be raised when the user is created, and use this exception as the context of a view that would redirect to the new page.
class NewUser(Exception):
pass
#view_config(context=NewUser)
def new_user_exception(request):
return HTTPFound(request.route_path('new_user'))
Make sure the exception is raised during the first request after the first login (after having created the user object, for example), and the user will be redirected to the right page.
You could also put the code for the welcome page directly in new_user_exception, but without redirection, this page would have the url asked by the user, whatever it was.
Another solution would be to tweak how the persona part is done. For that, I'm going to guess you are using pyramid_persona (I'm the writer :) ). If not, what I'm saying will still apply, and will be even simpler to do.
What you could do is :
Change the login view so that it includes in the response a boolean saying whether this is the first login or not.
Change the javascript to check this boolean, reload the page if it's not the first time, and redirect to the welcome page if it.
The code for the login view can use pyramid_persona's login view like this :
from pyramid_persona.views import login
#view_config(route_name='login')
def new_login(request):
response = login(request)
if response.status == 200: #the login worked
# tweak the response
return response
EDIT : There's now a part about this in pyramid_persona's documentation : Do extra work or verification at login.
I am using django-nonrel for my project on GAE. My requirement is that in my application at a time only one user should login with the given username. I tried to implement the following suggested approaches:
Allow only one concurrent login per user in django app and How can I detect multiple logins into a Django web application from different locations?
But the problem is that both of the approaches working on the development server but didn't work on google app engine. So I switched to django-signals as my alternate approach. I created one post_login signal which will store the username for every login user in a table Visitor in database. On every logout,other signal post_logout will remove the user from this table.The part of codes are as:
#signals.py
post_login = django.dispatch.Signal(providing_args=['request', 'user'])
post_logout = django.dispatch.Signal(providing_args=['request', 'user'])
#models.py
def login_handler(sender,user, **kwargs):
try:
result=Visitor.objects.get(user=user)
print "You already have login with your name"
except:
visitor=Visitor()
visitor.user=user
visitor.save()
post_login.connect(login_handler)
def logout_handler(sender,user, **kwargs):
try:
result=Visitor.objects.get(user=user)
result.delete()
except:
return False
post_logout.connect(logout_handler)
#django.contrib.auth.__init.py__
def login(request):
:
user_logged_in.send(sender=user.__class__, request=request, user=user)
post_login.send(sender=None,request=request, user=user)
def logout(request):
:
user_logged_out.send(sender=user.__class__, request=request, user=user)
post_logout.send(sender=None,request=request, user=user)
Please note that I am getting the following error while running my application on google app engine.
Error: Server Error
The server encountered an error and could not complete your request.
Also I am not able to login into Admin part of the application. Please help me to find right approach to implement this requirement or let me know where I am doing wrong.
Thanks for your patience for reading this huge problem description :-)
1.
You should not be editing the django framework like you are doing. Don't touch the files inside django.contrib.auth
If you wish to send a signal after someone is logged in, then send the signal in your view where you log the person in
2.
Not sure what your actual error is because you are not displaying it (if this is a dev environment set DEBUG = True to get a better stack trace) But by lookingat you code, you are not grabbing the arguments correctly in the signal handler. It should look more like this:
def login_handler(sender, **kwargs):
try:
user = kwargs['user']
request = kwargs['request']
result=Visitor.objects.get(user=user)
print "You already have login with your name"
except:
visitor=Visitor()
visitor.user=user
visitor.save()
post_login.connect(login_handler)