Excluding a Django app from being localized using a middleware - python

I need to localize a django project, but keep one of the applications (the blog) English only.
I wrote this middleware in order to achieve this:
from django.conf import settings
from django.core.urlresolvers import resolve
class DelocalizeMiddleware:
def process_request(self, request):
current_app_name = __name__.split('.')[-2]
match = resolve(request.path)
if match.app_name == current_app_name:
request.LANGUAGE_CODE = settings.LANGUAGE_CODE
Problem is, it assumes the middleware lies directly in the application module (e.g. blog/middleware.py) for retrieving the app name. Other projects might have the middleware in blog/middleware/delocalize.py or something else altogether.
What's the best way to retrieve the name of the currently running app?

You can use Django's resolve function to get the current app name.
https://docs.djangoproject.com/en/dev/topics/http/urls/#resolve

Related

Django settings LOGIN_REDIRECT_URL dynamic based on language

Let's say I have LOGIN_REDIRECT_URL='/foo/bar/' and I am on http://127.0.0.1/en/login/ and I login successfully. I will be redirected to http://127.0.0.1/foo/bar/ resulting in losing the language prefix. What should I do in order to maintain the language code in the url? Of course, I want all the other languages codes work and also the default one just like that:
http://127.0.0.1/en/login/ -> http://127.0.0.1/en/foo/bar/
http://127.0.0.1/login/ -> http://127.0.0.1/foo/bar/
http://127.0.0.1/ro/login/ -> http://127.0.0.1/ro/foo/bar/
In that case you can extend Django's LoginView and override the get_success_url method.
Something like this:
from django.contrib.auth.views import LoginView
from django.utils.translation import get_language
class CustomLoginView(LoginView):
def get_success_url(self):
# lang = get your language from the URL (it'd be helpful if you post your URLs in order to help better) or you can use like this:
lang = get_language()
url = '{}/{}/login'.format(yourbaseurl, lang)
return url
Assuming you are using Django auth and the LoginView from the framework, you can parametrize the URL to redirect to after logging in. The LOGIN_REDIRECT_URL is a fallback when it is not specified.
The LoginView attribute is called next. The next url can be set using a parameter from the previous page like ?next=<your_url>. Just don't forget to sanitize it using is_safe_url() from django.utils.http.

save() doesn't work in Mongoengine

I'm trying to perform a simple insert operation using Mongoengine and Django.
Regarding my project structure simply I have a project, AProject and an app, AnApp. I have a running mongo in a remote machine with an IP of X.X.X.X. I am able to insert document using Robomongo in it.
I have removed the default Database configuration part of the settings.py located inside the AProject directory. The newly added lines are shown below:
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
import mongoengine
# ----------- MongoDB stuff
from mongoengine import register_connection
register_connection(alias='default', name='AProject', host='X.X.X.X')
# ----------
Now let me show the models.py and the views.py located inside AnApp.
models.py
from mongoengine import Document, StringField
class Confession(Document):
confession = StringField(required=True)
views.py
from django.http import HttpResponse
from models import Confession
from mongoengine import connect
def index(request):
connect('HacettepeItiraf', alias='default')
confession = Confession()
confession.confession = 'First confession from the API'
print(confession.confession + ' Printable') # The output is --First confession from the API Printable--
print(confession.save()) # The output is --Confession object--
return HttpResponse(request)
The urls.py located inside AProject is simply as below:
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^confessions/', include('confession.urls')),
url(r'^admin/', admin.site.urls),
]
When I enter http://127.0.0.1:10000/confessions/ I see a blank screen which I expect. However there is nothing saved from the API. I get the expected output except Confession object.
How can I solve this problem?
EDIT:
I found the concrete proof that currently MongoEngine's support for Django is unstable and it is corresponding to Django version 1.9:
MongoEngine documentation on Django support states:
Django support has been split from the main MongoEngine repository. The legacy Django extension may be found bundled with the 0.9 release of MongoEngine.
and
6.1. Help Wanted!
The MongoEngine team is looking for help contributing and maintaining a new Django extension for MongoEngine! If you have Django experience and would like to help contribute to the project, please get in touch on the mailing list or by simply contributing on GitHub.
Which leads to this repo, where the following is stated:
THIS IS UNSTABLE PROJECT, IF YOU WANT TO USE IT - FIX WHAT YOU NEED
Right now we're targeting to get things working on Django 1.9
So it may be possible that it cannot play well with Django at this state or with your version and thus the problem occurs.
Initial attempt, leaving it here for legacy reasons.
I believe that the problem occurs on how you are initializing your object, although I do not have a set up to test this theory.
It is generally considered that is better to make a new object with the .create() method:
def index(request):
connect('HacettepeItiraf', alias='default')
confession = Confession.objects.create(
confession='First confession from the API'
)
print(confession.confession + ' Printable')
confession.save()
return HttpResponse(request)
Have a look at the Django & MongoDB tutorial for more details.
In this tutorial, the supported Django version is not mentioned, but I haven't found concrete proof that MongoDB Engine can or can't play well with Django version > 1.8.
Good luck :)

Flask - How to properly set global values

I'm currently working on a web app where I'm using Flask and the Flask-User extension to handle authorization. At the moment I have something like this:
#application.route('/dummy')
#roles_required('Admin')
#login_required
def dummy():
in my views.py file and something like this:
{% if current_user.is_authenticated and current_user.has_roles('Admin') %}
in my templates.
Now, there's been a few times where I've changed my mind in terms of role names and then had to search through the whole project to find and replace those usages. I wanted to define something like a ADMIN_ROLE global that can be accessed inside my views.py or any templates. I'd then just change a config file whenever I wanted to change a role's name.
I tried using my config.py setting ADMIN_ROLE = "Admin" and writing #roles_required(current_app.config['ADMIN_ROLE']) but that gives me the following error:
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in a way. To solve
this set up an application context with app.app_context(). See the
documentation for more information.
so that should be wrong. What would be the most correct way to accomplish what I'm trying?
As it says, you can only access config from within the app context. Normally, you do this:
with current_app.app_context():
admin_role = current_app.config['ADMIN_ROLE']
Because you're doing this in a decorator, I don't believe there's anyway to do that. I would suggest just using a separate module. Now, it doesn't appear that you can use python import statements in jinja, so we'll still use app.config for that. Basically we'll create a module with the desired roles and then import that into the config file and your routes file.
roles.py
ADMIN = "Admin"
USER = "User"
config.py
from roles import ADMIN, USER
ADMIN_ROLE = ADMIN
USER_ROLE = USER
routes.py
from roles import ADMIN, USER
#application.route('/dummy')
#roles_required(ADMIN)
#login_required
def dummy():
views.py
{% if current_user.is_authenticated and current_user.has_roles(app.config['ADMIN_ROLE']) %}

Password protect a whole django app

I am running a simple staging env on heroku and I am now looking to password protect the whole app with some sort of simple authentication
I am wondering if there is a simple app or middleware that already supports this.
Have tried looking around for solutions with Heroku / Cloudflare and django, but nothing seems really straight forward.
Django 1.3.1
I use django-lockdown for exactly this purpose. It allows you to add a simple password over the whole of a dev site, without having to add in any extra auth bits on your views that aren't used outside of a dev environment. It also means you can login as admin, or regular users to test whatever your site does
https://github.com/Dunedan/django-lockdown
I use Heroku and Lockdown with this bit of code in my settings.py file
USE_LOCKDOWN = os.environ.get('USE_LOCKDOWN', 'False') == 'True'
if USE_LOCKDOWN:
INSTALLED_APPS += ('lockdown',)
MIDDLEWARE_CLASSES += ('lockdown.middleware.LockdownMiddleware',)
LOCKDOWN_PASSWORDS = (os.environ.get('LOCKDOWN_PASSWORD', 'False'),)
LOCKDOWN_URL_EXCEPTIONS = (r'^/some/url/not/locked/down/$',)
Then obviously set a config var of USE_LOCKDOWN as True on my dev site, and False on my production site so no need to change the code for either.
Django's authentication framework has built-in utilities #login_required which helps you to password protect your view functions (and its corresponding "url" of course).
Usage like this:-
from django.contrib.auth.decorators import permission_required, login_required
#login_required
def view_organization(request, org_slug):
"""
Only permit a logged in user to view the organization.
"""
org = get_object_or_404(organization, slug=org_slug)
org_users = organizationuser.objects.filter(organization=org,\
organization__is_active=true)
template = 'organizations/view_organization.html'
template_vars = {'org_users': org_users, 'org': org}
return render(request, template, template_vars)
For advanced access control, use #permission_required decorator.

Django Middleware: Can't get urlredirect to work

So I'm very new to Django, but have completed the tutorials on (https://docs.djangoproject.com/en/1.4/intro/tutorial01/) several times and feel that I'm getting a pretty good handle on it.
The next item I'd like to tackle is creating , installing and configuring middleware (more specifically i'm trying to make it so that when local host accesses the site that it pulls up fine and when someone other than local host pulls it up that it forwards to google.com or some other random site.) I'm mainly doing this for experience building at the request of my boss, so any help would be greatly appreciated! :)
I've read the following sites, but can't seem to figure out what to do to get the url redirect to work.
$https://docs.djangoproject.com/en/dev/topics/http/middleware/?from=olddocs
$https://docs.djangoproject.com/en/dev/ref/middleware/
$http://djangosnippets.org/snippets/510/
Code that I've picked up from the above site (www.djangosnippets.org)
import re
from django.http import HttpResponsePermanentRedirect
from django.conf import settings
class UrlRedirectMiddleware:
"""
This middleware lets you match a specific url and redirect the request to a
new url.
You keep a tuple of url regex pattern/url redirect tuples on your site
settings, example:
URL_REDIRECTS = (
(r'www\.example\.com/hello/$', 'http://hello.example.com/'),
(r'www\.example2\.com/$', 'http://www.example.com/example2/'),
)
"""
def process_request(self, request):
host = request.META['HTTP_HOST'] + request.META['PATH_INFO']
for url_pattern, redirect_url in settings.URL_REDIRECTS:
regex = re.compile(url_pattern)
if regex.match(host):
return HttpResponsePermanentRedirect(redirect_url)
Add to your settings (assuming you are working with the development server):
e.g
URL_REDIRECTS = (
(r'127.0.0.1:8000/hello', 'http://www.google.com'),
)
Also add the UrlRedirectMiddleware python-path to your MIDDLEWARE_CLASSES in your settings.
e.g if your UrlRedirectMiddleware is defined in a module called my_middle.py inside an application called app
add 'app.my_middle.UrlRedirectMiddleware' to your MIDDLEWARE_CLASSES

Categories