Is it possible to redefine reverse in a Django project? - python

I have some custom logic that needs to be executed every single time a URL is reversed, even for third-party apps. My project is a multitenant web app, and the tenant is identified based on the URL. There isn't a single valid URL that doesn't include a tenant identifier.
I already have a wrapper function around reverse, but now I need a way to tell every installed app to use it. The wrapper around reverse uses a thread-local to inject the identifier into the resulting URL. I could write this function as a decorator on reverse, but I don't know where to do the actual decoration.
Moderately Firm Constraint: I'm already using 3 3rd-party apps, and I'll probably add more. A solution should not require me to modify the source code of all these third-party apps. I don't relish the idea of maintaining patches on top of multiple 3rd-party source trees if there is an easier way. I can make the documentation abundantly clear that reverse has been decorated.
The Original Question: Where could I make such a change that guarantees it would apply to every invocation of reverse?
Possible Alternate Question: What's a better way of making sure that every URL—including those generated by 3rd-party apps—gets the tenant identifier?
BTW, I'm open to a better way to handle any of this except the embedding of the tenant-id in the URL; that decision is pretty set in stone right now. Thanks.
Thanks.

only way so that django reverse is replaced by ur_reverse is
django.core.urlresolvers.reverse = ur_reverse
or if you like decorator syntactic sugar
django.core.urlresolvers.reverse = ur_reverse_decorator(django.core.urlresolvers.reverse )
which i would not advice(and many will shout), unless you are not willing to change every usage of reverse with ur_reverse

Related

What is the convention for separating multiple words on a flask route?

I have these 2 routes:
api.add_resource(X, "/<string:stage>/api/sales/by-type")
api.add_resource(Y, "/<string:stage>/api/sales/filters/by-type")
Should it be /by_type or /by-type? /by/type would be weird because /by would be a route by itself, which makes no sense. Can't find any docs about it.
#nitul was right, it's about API design in general, but hyphens are commonly used in urls even it's not standard or official but seen as the best practice, seo friendly and urls are more elegant and pretty.
in other hand, i would like to drew your attention about some particular/extra parameters in urls like filters, sorting and pagination, it does more sens to use them as extra arguments ?type=TYPE along with your base/canonical url /<string:stage>/api/sales because the two routes you mentioned are logically the same at the end. Have a look at this good post https://www.moesif.com/blog/technical/api-design/REST-API-Design-Filtering-Sorting-and-Pagination/ it elaborates more the topic with good patterns to adopt. that's been said, you'll need only one route :
api.add_resource(X, "/<string:stage>/api/sales")
and then depending on extra arguments eg: ?type=TYPE in the url you return the appropriate set of objects and this way your API are more compact (you avoid redundancy) and maintainable and extensible.
and as bonus, since you are using Flask and depending on your need (if any), think of Custom URL Converter (this topic https://exploreflask.com/en/latest/views.html#custom-converters will help you)

Django. Check in template or use an extra field?

I have some text fields in my Django model that are filled by a script, with values in English (the list of values is known).
But the app is actually made for Russian clients only. I'd like to translate those fields into Russian, and here comes a little question. These values are taken from an API response, which means I should check the value to translate it. What's faster: to check and translate fields in template or to make extra fields and translate strings in the Python script?
The problem is overhead of compiling Templates when rendering. So the more complicated the template gets (method calls etc), the performance tends to get slow (like py files are converted to pyc). Django has template caching but that also is limited (I don't know how much). I have faced performance issue because of lot of logic in templates. Plus its always good to have a dumb client (template). I will prefer the Python approach because of the idea to keep client thin and not because of the performance gap. Plus if tomorrow you need to add one more language then changing templates is always going to be difficult then server.

Python design advice

I have written a generic framework in python for some particular type of task. It is a webserver which serves different requests and operations. This framework can be used by many projects and each one has a different set of validation rules. Right now, I'm just updating my script for each project.
I'm thinking of externalizing this validation part, how do I go about this? The validations are more than mere field content validations; I'm thinking of having a config file which maps incoming request <-> validationModule something like /site1/a/b.xml=validateSite1.py and importing this module in an if condition if the request is for site1. So I'll have generic framework scripts + individual scripts for each site.
Is there a cleaner way to do this?
I think it'd be better to use Python itself as the top-level mapping from URL paths to validation modules. A configuration might look like this:
import site1
import site2
def dispatch(uri):
if uri.startswith('/site1/'):
return site1.validate(uri)
elif uri.startswith('/site2/):
return site2.validate(uri)
This simple example might tempt you to "abstract" it out into a more "generic framework" that turns strings into filenames to use as validation scripts. Here are some advantages of the doing the above instead:
Performance: site modules are imported just once, we don't look up filenames per request.
Flexibility: if you decide later that the dispatching logic is more complicated, you can easily use arbitrary Python code to deal with it. There will never be a need to extend your mapping system itself--only the config files that require more complexity.
Single language.

Python routes - I'm trying to set the format extension but it's failing

I'm trying to setup my Routes and enable an optional 'format' extension to specify whether the page should load as a standard HTML page or within a lightbox.
Following this http://routes.groovie.org/setting_up.html#format-extensions, I've come up with:
map.connect('/info/test{.format:lightbox}', controller='front', action='test')
class FrontController(BaseController):
def test(self, format='html'):
print format
This fails. My route gets screwed up and the URL appears as /front/test rather than /info/test. It's falling back to the /{controller}/{action}.
How do I allow for the format extension? :/
Generally:
http://pylonsbook.com/en/1.1/urls-routing-and-dispatch.html#pylons-routing-in-detail
Routes then searches each of the routes in the route map from top to bottom until it finds a route that matches the URL. Because matching is done from top to bottom, you are always advised to put your custom routes below the ones that Pylons provides to ensure you don’t accidentally interfere with the default behavior of Pylons. More generally speaking, you should always put your most general routes at the bottom of the route map so that they don’t accidentally get matched before a more specific route lower down in the route map.
The first thing I'd check is that you're using routes 1.12. Several distros are still on 1.11, which doesn't support format extensions.
Second, check the order in which your routes are defined. It matters.

Dynamically select database based on request

I'm trying to keep my RESTful site DRY, and I can't come up with a good way to factor out the code to dynamically select from each "user's" separate database. We've got a separate database for each client. This comes in as a part of the URL, and is passed into each view as a keyword arg. I want to give each and every view the behavior of accessing the corresponding database WITHOUT have to make sure each programmer writing a view remembers to use
Thing.objects.using(user).all()
and
t = Thing()
t.save(using=user)
every time. It seems like there ought to be some way to intercept the request and set the default database based on the args to the view before it hits the view, allowing us to use the usual
Thing.objects.all()
This would also have the advantage of factoring out all the user resolution code into a more appropriate place.
We do this by the following technique.
Apache picks off the first part of the path and routes this to a specific mod_wsgi Daemon.
Each mod_wsgi daemon is a different customer's installation.
We have many parallel customers, each with (nearly) identical code, all based off a single common installation of the base software.
Each customer has a separate settings.py with their unique configuration.
They don't (actually can't) know about each other because Apache has peeled off the top layer of the path for us.

Categories

Resources