Is there something between middleware and view in Django so that I can plug my code into? - django

Is there something between middleware and view so that I can plug my code or do I have to subclass something from Django to provide this functionality?
Let me first explain why I need this, maybe there is a better solution that you can suggest. I want to restrict some of my url's based on some configuration. And,
- I want this configuration to be part of url configuration
- According to the config provided, I want to redirect, etc to some other view.
What I mean by 'part of url configuration' is something like the following.
url(r'^admin/blah/blah$', do_something, name='admin-blah-blah', {'security_level': 'very_secure', 'auth_method' : 'oauth', 'auth_url', 'http://www.foo.com'})
It seems like it is something that should be done by middlewares, but I don't want to do it with middlewares for 2 reasons.
- I don't want to maintain a separate config.
- I don't want to do regex matching for url patterns one more time, url resolver is already doing that
So if I can just find a way to plug some functionality just before view and can reach the configuration provided, it solves my problem.

Sounds like you could do this with a decorator on your views:
#restrict_url(security_level='very_secure', auth_method='oauth',
auth_url= 'http://www.foo.com')
def my_view(request):
... etc ...
You can get some ideas of how to write the restrict_url decorator by looking at the ones provided in django.contrib.auth.decorators.

Related

How to change url params (query_string) in django rest framework before handle request?

Because I need compatible with old client.
I use django-rest-framework and django_filter.
For example, when I recevie an request http://0.0.0.0:8000/api/exercises/?pk=13, i want change the params so http://0.0.0.0:8000/api/exercises/?id=13.
Others:
http://0.0.0.0:8000/api/exercises/?displayName=ABC
change to
http://0.0.0.0:8000/api/exercises/?display_name=ABC
http://0.0.0.0:8000/api/exercises/?target=1,2
change to
http://0.0.0.0:8000/api/exercises/?target=1&target=2
Is there any place I can write code before handle the request?
I try to change request.environ['QUERY_STRING'] and request.META['QUERY_STRING'] in middleware, but not work.
Thanks.
I believe you can make use of the RedirectView and override the get_redirect_url method to map the change in query params.
For implementation details, you can refer to the official docs.
You can use django's redirect function for this. For that in your old views just redirect it to your new views.
A simple Example -
def my_old_view(request,pk):
...
return redirect(f'/api/excersise/?id={pk}')
So if someone enters your old URL it will be redirected to new one without any issues.

How do you return a complete url with get_success_url(self) in django?

How do you return a url using get_success_url(self) in django without using reverse for a generic view? Basically, I want to have something as below.
def get_success_url(self):
url = self.object.url # This is a charfield with "https://stackoverflow.com/questions/ask"
return url
I know that people often use reverse when returning a url, but I would like do it like above. Thank you, and please write any questions you have. By the way, I never tested the above code, but I don't know if it will work properly.
"reverse(..)" is part of the django logic to store the url structure in urlpatterns in ONE place and then in the whole code refere to it in the moment of the request being executed via the name. If you do not want to follow that logic - feel free to store anything you like in your "object.url" and return it like you propose. You then just do not follow the django urlpattern idea. Up to you to decide if that is important or "right" in your case.
If the url targets outside our own server space, reverse is anyway not usefull as those urls are not part of your urlpattens.

Add custom url action parameter to django-cms

The common url action parameters in django-cms are for example: ?edit to enter Edit-mode, ?toolbar_off to disable/hide the toolbar.
Now I'd like to add a new action parameter e.g. ?logout which just logs out the user no matter on which url he/she currently is. I'd tried to include this in the urls.py with the following pattern:
url(r'^.*\?logout$', RedirectView.as_view(url='/admin/logout/')),
I read in another SO answer that you shouldn't catch URL Params with an url pattern...
Should I do this in a kind of middleware? Or where else?
Using django==1.11, django-cms==3.5.3
This should definily go into a middleware. It would probably work as well as an url pattern, but is kind of not "how you do it" - at least I never saw anything like it in a tutorial or documentation.

django internalization in urls? how to make urls like this: "en/articles" and "pt/artigos"...?

Hy!
I would need to make urls based on language.
Example:
If I had the language english and subcategory named "articles" then the url might be like this:
/en/articles/...
If the language were portuguese and subcategory already translated is "artigos" then the url will be:
/pt/artigos/...
How can I do it?
I must use the urls.py or some monkeypatches?
thanks
This features is already existing in the yet-to-be released version 1.4. You can read about it in the release note.
If your really need this feature, and no existing app feets your needs, you can still try to apply the corresponding patch yourself.
Django LocaleURL is a piece of middleware that does exactly this. The documentation can be found in the source, or online.
Edit: I read over the fact that you want to translate the url itself... I'm not aware of any piece of code that provides this. Perhaps you could extend the LocalURL middleware to take care of the translations for you. Say you have a regex match like (?P<articles>\w+), you could in the middleware determine which view you want to use. Something like the following mapping perhaps?
if article_slug in ['articles', 'artigos', 'article']:
article(request) # Call the article view
I've been using transurlvania with great success, it does exactly what you need and more, however i see that in the next Django release django-i18nurls will be included in django core so perhaps it would be better to learn that

Is it possible to make URLs conditional with django?

I'm using the middleware to detect the subdomain and place a corresponding object in the request scope. Would it be possible to take it further and declare that the subdomain implements these urls but not those?
Something like?
if request.subdomain.is_blue:
include(these.urls)
the urlconf is executed at startup time, not for each request; so you don't have the opportunity to include or not according to the URL used to acess.
the best would be to write your own middleware, or a restricting decorator (like #login_required), it's quite easy to write your own decorator (i like them more than middlewares for most specific tasks)
You can poke around with request.urlconf, but that can break things