Django multi-user saas - python

I'm creating a small saas for learning purposes... I know that the best way to go is to have a separate schema for each user... But my saas is a small app and I really don't need separate schemas plus it would complicate stuff (later alterations to the schema)... So I'm going to use the same schema for all users and just append each user's ID to the entry and then display only the user's entries upon login.
Is there a way I can "prepend" user's ID upon login through middleware? Or do I need to adjust all the queries (filter by user's ID)? I already store the user's ID to his entries... so I need this only for select's.
Thank you!

I don't know of any way to automatically filter querysets based on request.user. This is because the ORM is not coupled with django.contrib.auth.
I tried two SaaS designs:
1 database for all sites, and manual filtering on all querysets. Of course this made django.contrib.admin not possible out of the box. It might be possible to enable django.contrib.admin with a really tight setup of django-authority or maybe even other django per-object permission packages (google cached version because djangopackages.com is down ATM).
1 database per site, that's just easier, keeps the code cleaner, and enables django.contrib.admin out of the box, which can be really cool if you install a django admin theme. Also I enabled django.contrib.admindoc as well as django-dbtemplates.
(Apparently in your case, 1 site = 1 user, but the concept is the same)
I prefer the second implementation because it's obviously a lot less development work, which is compensated by a little system administration.

Related

How to Replace Entire default Djnago Admin with custom Admin

I want to replace the default Django Admin templates with a completely revamped bootstrap version. The data in the Dashboard should be populated from the DB. How do I work with templated files ? Which files should be overriden ? In which template tag does HTML code go ?
From django docs on admin:
The admin’s recommended use is limited to an organization’s internal management tool. It’s not intended for building your entire front end around.
It's possible to change templates to do what you want, but that will be very complex - you have to basically rewrite most of the templates, get to know how it is working internally and probably change that too to your own design (after all, you are going to show specific details, like charts, data and so).
You will faster to achieve results if you going to build your own app, that will work exactly like you need without multiple fixes. Does it have to use js frameworks depends entirely on your requirements. Usually they are much more simple for admin backends, that are going to be used by owners, not clients. Anyway, if you don't have experience or knowledge in this, you will probably better off with just plain static django templates.
Django admin is just a same app as the ones you build, so limitations will be the same. Security wise, it doesn't offer much that you can't do yourself - make sure you have permissions set in models/views. Read more about security in django.
From functionality point of view, django admin just comes with CRUD access to your models, which can be done quite quickly. Once you past that, you will have much easier time adding functionality to your own app instead of overriding django admin.
Overall, I advise you to build your app for CMS-like admin panel. JS frameworks is neat, but that require burden of multiple additional tests (with api mocks), constant swapping between adding api / writing a component and much higher time consumption overall.

Backend architecture for SaaS product in django

I'm writing the backend for a SaaS application in django. Need some guidance on the architecture.
So the product will have 2 offerings: a general one where all users will share the same database and a premium one with a dedicated database. How I'm planning to translate this to django is the following:
Within the django project, there'll be one app for the general offering.
For every premium client, there'll be a separate app.
Each app has the same models.
Every app communicates with a separate database. Achieved this using: stackoverflow post and django documentation
I'll write views for all the APIs in the project's views.py, not inside any app and decide on the basis of a token which app's models to communicate to.
The problems I see right now with this architecture:
In all of the views, I'll have to write a lot of conditional statements once the number of premium clients increases.
Onboarding of new premium clients requires quite a bit of code change.
Code duplication in models.py of all the different apps. But it's almost similar to writing statements for creating tables in a new database every time a premium client signs up. Comments?
Please advise me on the architecture as a whole. I went through a lot of articles and stack overflow posts before going this way, but none were completely specific to django so I'm not 100% confident. Much thanks in advance.
If the functionality of the free and premium offerings will be exactly the same you shouldn't need any code duplication. This is of course a big IF, because it's very conceivable that you'll add extra features to the premium offering.
If the functionality will be exactly the same then all you need to do is add any new premium databases to your settings.py and use a middleware to determine which database your models should communicate with (using the using attribute), and for the shared database add an owner column to every table that records who the owner of that row is so you can filter querysets appropriately.

Using Django's cache if and only if the user is logged-out?

I need to implement caching on my Django 1.8 site (to speed up rendering, obviously). Plan is to use Memcache, although this question isn't directly tied to it.
Right now, a lot of traffic goes to a specific set of blog posts that remain constant. But, there is a universal dynamic topbar across the whole site which can vary from logged-in user to logged-in user, so I need a cache function that kicks in if and only if the user is anonymous - e.g. one that is bypassed altogether if the user is logged in.
It looks like Django's builtin cache doesn't really distinguish between logged-in and logged-out users, so if I use it, there will be adverse effects for logged-in people.
I'll probably have to write my own cache decorator/cache function using the lower-level cache API and attach it to all of the logged-out-accessible URLs/views on the site. While it doesn't seem difficult, this does seem like an incredibly common feature. Is there really nothing in Django that does this properly already? I'm worried I might have missed something and am reimplementing the wheel.
Thank you!
First of all template caching is over rated. First use django debug toolbar to determine if template rendering is indeed slow on your django installation. I am betting that it's not the bottleneck. If you find that it's slow. YOu can cache on a per user basis as follows:
{% cache 300 FULL_PAGE request.build_absolute_uri request.user %}
The first parameter to the cache template tag is the timeout and the second one is the name others uniquely identify the fragment.

Flask-Admin vs Flask-AppBuilder

I am new to Flask and have noticed that there are two plugins that enable CRUD views and authorized login, Flask-Admin and Flask-AppBuilder.
These two features interest me along with nice Master-Detail views for my model, where I can see both the rows of the master table and the relevant details on the same screen.
Any idea which one to prefer? I see that Flask-AppBuilder has far more commits in Github, while Flask-Admin many more stars.
How to tell the difference, without spending too much time with the wrong choice?
I am the developer of Flask-AppBuilder, so maybe a strong bias here. I will try to give you my most honest view. I do not know Flask-Admin that much, so i will probably make some mistakes.
Flask-Admin and Flask-AppBuilder:
Will both give you an admin interface for Flask with bootstrap.
Will both make their best to get out of your way.
Will both help you develop Flask more Object Oriented style.
Will both let you override almost everything on the admin templates.
Will both support Babel.
Both inspired on Django-Admin.
Pros for Flask-AppBuilder:
Has a nicer look and feel (bias? maybe...).
Security has been taken care of for you, and supports out of the box, database, LDAP, OpenID, Web server integrated (REMOTE_USER), and in the near future OAuth too. Will let you extend the user model and security views.
Granular permissions, creates one permission for each web exposed method and action (you have to try it).
You can easily render Google graphs.
Smaller project, it's easier to request new features, and get your pull requests merged.
MasterDetail views and multiple views can be setup easily.
Backends: supports SQLAlchemy, MongoEngine, GenericInterface (you can integrate with your own builtin data still a bit beta).
Pros for Flask-Admin:
You have to assemble your own security (models, views, auth etc), it's ready though to integrate nicely with flask-security. This can be a pro or a con depending on what you want.
Builtin File Admin.
Bigger project with bigger community.
Backends: supports SQLAlchemy, GeoAlchemy, MongoEngine, Pewee and PyMongo.
Better support for MongoEngine (EmbeddedDocument, ListFields etc..).
On the overall i think Flask-Admin makes no assumptions at all like Flask, you have to code more, but this will let you be more free. Flask-AppBuilder makes some assumptions (on security), you will have to code much less, but some things can get on your way if your building very specific security models.
Hope this helps you and others, i tried my best to keep the bias out.
For me, master/detail is the major feature. That led me to use Flask AppBuilder to create ApiLogicServer:
With 1 command, create a database API, to unblock UI development. Also, a multi-page web app, to engage Business Users - early in the project. Declare logic with spreadsheet-like rules - 40X more concise than code, extensible with Python - for remarkable business agility.

Django : Project consuming data from REST API, How to use external apps in this system?

I have a Django web front-end that consumes data from a REST API backend.
Even the users are made and created on the backend.
My Problem :
How to use 3rd party apps within this system, that heavily depend on django models/ORM ?
Is there something that can provide some bridge between the REST API resources and the ORM?
How can this problem be dealt with ?
Update
DRY principal seems to be failing in this situation.
Probably things have changed since this question has been originally posted. Now there are a couple of interesting related questions on StackOverflow about this topic.
To code yourself a solution as explained in this answer, you can create an external service layer (aka services.py) and write there the logic to access the external resources. Your views will consume this layer, and make the proper actions. There are other questions that provide help on how to pass information from the original request received by the django-view to the external service like this or this
There is also a django app that takes this situation into account as explained in this answer. django-roa uses the Resource Oriented Architecture paradigm to solve this.
I'm facing a similar obstacle with a new ecommerce project.
The project is a front end to a full-fledged store management software (CMS+ERP+CRM). It needs to use the master product database, but have its own entries for product reviews, ratings and so on.
The initial thought was to make a cached copy of the master database. The website will benefit from fast loading times for the cached items, but the implementation is not trivial.
After some considerations, the selected approach was updating the website's DB from the management program. This way the website's copy will always be correct, and most of the implementation doesn't need to worry about REST services (it'll still be used for user registration, shipment tracking etc.)
In your case, where you can't have the service update your own database remotely, you need to come up with a mechanism that allows you to refer to REST recourses like regular models, and that caches them in the background.
Important note: research for a way to make sure the cache is always correct (non-dirty)...
I'm not sure I completely understand your question or requirements. The way I am reading it, you have a primary back-end which is basically a black-box, and you want to use some 3rd-party apps in your project which use the Django ORM.
I am unclear as to why there would be a need for being able to have a two-way synchronization between the two data-stores. The users of your project would be returned data from your primary back-end, and from the project's ORM.
Since you are concerned about saving the "ORM" data in your primary back-end, maybe you would consider creating a Transaction Middleware that would fire any time ORM data gets updated, which could serialize the structure being saved and transmit it to your REST API. This REST API, I assume, is able to accept arbitrary data structures?
You'll probably at least want to use some form of middleware, and maybe a utility module/class to help form the "bridge".

Categories