How to protect objects from deletion in Django? - python

I have a settings app inside my project, and every record in DB table that this app uses, represents particular setting.
And it is important that settings always must be consistent, so Im looking for way to protect them from accidental deletion by admin-panel users, or by buggy code.
Another cases for this feature might be - error messages stored in DB and available for editing in admin-site or templates for email messages for web-site users.
Possible solutions that I have in mind:
- Store each setting as table column or multiple columns, so the table will extends column-wise, not row-wise. Pros - simple, reliable, Cons - ugly
- DB-side solution.
- Implement some kind of permissions system which will control access for CRUD operations based on objects ownership, like file system permissions in Linux. Pros - less ugly, abstract from DB, Cons - I have no idea yet how to make easy and elegant implementation of it for Django.
Does anybody have better ideas?

The short answer is: if you don't want someone to have certain database abilities don't grant them. It appears that you are thinking there are admin panel superusers and everyone else.
Django allows much more fine grained control over Users, Permissions, Authorization, and even Admin Panel privileges. Indeed, too much control to elaborate here when the documentation does such a good job of it.

I'm not sure I completely understood your question, but here it goes:
I see two ways of protecting a model for being deleted:
Override the delete() method, and make it check a set of rules that enforce the consistency you require. E.g. if one of the consistency rules fail, you raise an exception to be properly handled.
The other is through autorization, aka permissions. You can manage permissions users have to delete particular models, as explained in this answer.
I notice that Django default permissions API does not support specific object's permissions, only permissions applied on models. However, there are third-party apps that provide this, such as this one.

In Django there is no real built-in way (that I am aware of) that prevents "accidental deletion". If you are using the admin, they do provide confirmation pages whenever you want to delete a record that can help curb the potential problem. As #msw mentioned, the user authentication system is designed to help you enforce permissions, but would not prevent accidental deletions if the individual has the proper permission to begin with...
...an alternative strategy would be to prevent deletions on the database entirely (at the web application level). You can give the "illusion" of a delete from the user's perspective by flagging and filtering out any "deleted" records to your user. That way, restoring information would be as simple as toggling/resetting the flag in the record. You would have to override the proper deletion signals as well.

Related

User defined template Django

Is there a way to enable application users to create their own template within the django app? One example would be how MailChimp enables users to create their own custom email template.
Currently i'm thinking of creating a model that captures information the user wants to display. that model can point to a template and populate it with the information the user wants to display. But is there a better way?
As stated in the docs:
Warning
The template system isn’t safe against untrusted template authors. For example, a site shouldn’t allow its users to provide their own templates, since template authors can do things like perform XSS attacks and access properties of template variables that may contain sensitive information.
Having a user define templates, even if the templates are stored in a model, can lead to xss vulnerabilities, and will be extremely difficult to implement safely.
Another answered noted a warning from the docs that included:
access properties of template variables that may contain sensitive information
This is a big concern. All Django tables are linked together, often in "magical" ways. The template system does not concern itself with permissions granted to authenticated users. If a template can be processed then it will process anything & everything that it can - i.e., if a link between tables exists, it will follow it. This means that something like a Customer record that is linked to a User record that is linked to Vendor records to Item records, etc. could allow any user (or at least, any user with permission to create a template) to view almost any data in the system. They would not, at least with the standard User package, be able to see User passwords. But they could get to almost anything else. For example, they might be able to figure out who else is using the system, how much people are paying, names of administrators (very useful for phishing!), etc.
So while it would be relatively easy to create a user-defined Django template system, it is not a good idea, at least not on any publicly accessible system.

Python / Django multi-tenancy solution

I could use some help creating a plan of attack for a project I'm working on.
Imagine that the site is for a group that oversees regional sales offices, distributed around the world. The purpose of this project is to let superusers spin up a new sub-site specific to each and every office, at a fast pace -- sites are added on a frequent basis. The office sub-sites should be wholly contained with "admin" users specific to that sub-site and should be user-friendly CMS. A superuser should be able to step in and manage all of these office sub-sites.
In addition to the self-contained office sub-site instance, there is also a need for each sub-site to manage contacts, leads, etc and store this in one central area for the superusers.
I've done a few sites using Django, but never anything multi-tenant. I'd like suggestions for technologies to use or tutorials/documentation that might be helpful.
Requirements:
Each sub-site uses the same source (templates, JS, available features, etc), but can be modified to reflect custom content within the templates.
Assigned subdomains (with an option of using a fully qualified domain) per sub-site, configured within the project, not in a hardcoded settings file.
Sub-site specific user access controls, in addition to superusers who can access all sub-sites.
The ability to provide an "independent" CMS for each sub-site. i.e., A sub-site admin only sees their content. My preference for this project would be django-cms, but I'm open to suggestions.
Support for apps that pool the data from all the sub-sites, but limit sub-site "admins" to only viewing their records into that app.
Considering the above, what approach would you recommend? I am open to reconsidering technologies, but I would like to stick with Python.
There is a great app called django-tenant-schemas that uses PostgreSQL schemas mechanism to create multi-tenancy.
What you get is specyfing SHARED_APPS that contain objects shared across all the schemas (sub-sites), and TENANT_APPS that contain objects specific for a sub-site, i.e. users, records etc. The schemas are completely isolated from each other.
Each PostgreSQL schema is tied to a domain url, so that middleware checks the HOST part of the request and sets the db connection's schema to appriopriate one.
In addition, it allows you to define a PUBLIC_SCHEMA_URLCONF which allows you to specify urlconf file for public schema - the meta site that is not tied to any sub-site.
Sorry for quick and dirty answer, i just share what i've done to achieve multi tenancy:
django-tenancy I like the author's approach of using "dynamic model"
django-dynamicsite This is where dynamic SITE_ID based on domain will be linked to a tenant
Both libraries above, when combined, is able to serve a django instance which is multi-tenant, and flexible. What i mean flexible here is: you can define any model whether is it "tenant" or "global". So, you can have a site with global user but per tenant product catalogue, or per tenant + product. From many django app i've tried, this is the most flexible way to achieve multi tenancy
The Django based CMS Mezzanine also has multi-tenancy support.
It has most of the features you requested except the sub-site user controls I think. The admin page can be separated by site for admin users, but the normal users not.
However, if you dont need a CMS this might be an overkill for your use-case, But I wanted to mention it here for completeness.
I have been trying to use django-tenants for a while along with Wagtail but this combination didn't work very well, or let me say, despite of a lot of try I was not able to get wagtail admin-page working correctly. I think will try to switch to django-tenant-schemas which I more widely used .
NOTE: django-tenant-schemas is not maintained now.

What is a good Django workflow?

I'm a beginner to Python and Django.
When starting a new project what do you do first before diving into the code?
For example, one could take the following steps:
Configure the settings.py file first
Configure models.py to lay out data structure
Create template files
Define the views/pages
Syncdb
etc
So my question is, what is a good workflow to get through the required steps for a Django application? This also serves as a checklist of things to do. In the definitive guide to Django, the author talks about approaching top down or bottom up. Can anyone expand further on this and perhaps share their process?
Thanks.
Follow the Agile approach. Finish one small case, from the start to the end. From the models to the tests to user experience. Then build on it. Iterate.
Thats the right way to software development.
To do it efficiently, you need: (don't bother right away, you will need it.)
Automated schema migration, automated build system, auto updating and deployment. - None of these, django has got anything to do with. Use pip, fabric, hudson, twill and south appropriately.
Take care not to over burden yourself with all these right away, particularly since you say, you are beginning.
the required steps for a Django application?
There are two required steps.
Write the settings. Write the urls.py
The rest of the steps are optional.
This also serves as a checklist of things to do.
Bad policy. You don't need a checklist of Django features. You need a collection of use cases or user stories which you must implement.
For some reason, you've omitted the two most important and valuable features of Django. Configure the default admin interface and write unit tests. The default admin interface is very high value. Unit testing is absolutely central.
You do it like this.
Gather use cases.
Prioritize the use cases.
Define the actors. The classes of actors becomes groups in the security model.
Define enough "applications" to satisfy the first release of use cases. Define the url structure. Cool URL's don't change.
Build the first use case: models (including security), admin, urls, tests, forms, views and templates. Note that these are the file names (models.py, admin.py, ...) except for templates. Also note that forms and admin should be defined in separate modules even though this isn't required. Also note that templates will be split between a generic templates directory for top-level stuff and application-specific templates.
Build the second use case: models (including security), admin, urls, tests, forms, views and templates.
...
n. Package for release. Tweak up the settings. Configure database and mod-wsgi
I personally can't make a template without writing the views (unless it's a photoshop draft) but in general that's the way I go after I have a plan.
What's extremely important for me is that I don't dive head-first into the code, and that I spend time mocking up the model structure based on the "screens" or "pages" that the user will see.
Once I have a user experience defined, I make sure the backend is robust enough to handle that experience. If I don't visualize the user experience, details get left out that are certainly accomplishable in the shell but not ideal for the website, default django admin, etc.
There are always tradeoffs between agile development and a huge spec: I think there's an important balance. Agile is good: there's no point planning every detail before writing your first line of code, as your needs will change by the time you get to the end. You don't know how your users will really use the site.
On the other hand, without a plan, you can end up with a messy foundation that affects all future code.
An educated guess is a good start. Don't think or assume too much, but definitely have a clear idea how your users will interact with your site for stage 1.
Always try to remember about a DRY rule. For example, why to write RequestContext every new view is defined, where you can simply write a function once, which will add it for you. Good description is here in another topic.
Try to keep a code written one way. Each time you upgrade a schema of your view, edit it in all already written views. That will help keep your code clear and save a lot time for you in future.
Generally good rule, and how do I write my applications is the rule of small steps. Start with writing a settings and urls, then add one model and one view. When it works, modify - add another models or another views. You won't even notice, when your project becomes bigger and bigger.
And the last useful rule for clarity of all the source. Keep files in folders. If you have two subsites based one one (for example "accounts" and "blogs") create two directories names the same. Remeber to put init.py file in each directory. It's really easy to forget. With this practice it's easy to write models and views dedicated to each category. By the way it's a good practice to keep urls like in a tree structure. Main urls.py should contain only links like this one:
(r'^accounts/', include('your_main_name.accounts.urls')),
and of course all media, static, css and so on. In accounts directory urls keep:
urlpatterns = patterns('your_main_name.accounts.views',
url(r'^$', 'index', name='index'),
)
with all views subdirectories.
Last one - keep code clear with actuall django version. Remeber, that the 3.0 release is comming soon.
Hope this will help.
I find that my process varies depending on a lot of variables, mainly whether I know something will work or if I'm experimenting and also whether I'm developing on my production server or in a development environment.
For example, I often do my development directly on the deployment server (most of my work is for intranet projects so there isn't any security risk, etc). But when I do this I really need to make sure the settings and urls are setup first and that gunicorn and nginx are configured.
If I know something should work, or am setting up a generic base set of code, sometimes I'll do all that coding for views and models before I even get enough setup to even run the development server. But when experimenting with new code I find it's good to be able to test every step of the way, so in that case you need your servers running.
In general I do settings, models, syncdb, views, urls, templates, collectstatic, graphics/aesthetics
In general I leave my base.html very plain until the everything else is working, then I add css/js etc.
I guess my point here is that there isn't really a wrong answer for how you do it, and there isn't even only one best practice (as far as I'm concerned). When you do more work, you'll find what you are comfortable with and it'll even vary from project to project.
Good luck, hopefully you learn to love django!
here is something I do in general,
configure basic settings
configure root url.py
configure settings, url.py for static (media) files
create model
sync db
write views (use simple template, if needed)
once you are done with back end implementation
think about UI
prepare styles, scripts
start working on template implementation

What are the best uses for the Django Admin app?

On the website, it says this:
One of the most powerful parts of
Django is the automatic admin
interface. It reads metadata in your
model to provide a powerful and
production-ready interface that
content producers can immediately use
to start adding content to the site.
In this document, we discuss how to
activate, use and customize Django’s
admin interface.admin interface.
So what? I still don't understand what the Admin interface is used for. Is it like a PHPMYADMIN? Why would I ever need this?
Let's say you create a model called Entry. IE an extremely simple blog. You write a view to show all the entries on the front page. Now how do you put those entries on the webpage? How do you edit them?
Enter the admin. You register your model with the admin, create a superuser and log in to your running webapp. It's there, with a fully functional interface for creating the entries.
Some of the uses I can think of -
Editing data or Adding data. If you have any sort of data entry tasks, the admin app handles it like a breeze. Django’s admin especially shines when non-technical users need to be able to enter data.
If you have understood above point, then this makes it possible for programmers to work along with designers and content producers!
Permissions - An admin interface can be used to give permissions, create groups with similar permissions, make more than one administrators etc. (i.e. if you have a login kinda site).
Inspecting data models - when I have defined a new model, I call it up in the admin and enter some dummy data.
Managing acquired data - basically what a moderator does in case of auto-generated content sites.
Block out buggy features - Also if you tweak it a little, you can create an interface wherein say some new feature you coded is buggy. You could disable it from admin interface.
Think of the power this gives in a big organization where everyone need not know programming.

Fully customized login system in Django?

I am currently writing an application which I plan to sell as SaaS. Without giving away "secrets," I can say that it is basically a "document editing system" in which many users will be submitting documents.
The basic heirarchy is this:
Institution
Individual
Document
Sub-document
So each Individual should be able to BROWSE all documents that were submitted by anybody in their institution, but should only be able to EDIT documents that they created.
No individual should even be aware of the existence of another Institution--that should all be completely hidden.
I have written a Django/Python class that would facilitate this, but every document regarding authentication that I have read requires that I use the User object. Is this just a limitation of Django, or is there a way to do this?
If there is a way, how can I get my own "Individual" class details attached to the "request" objects so I can validate the things I should be showing the users?
What you're looking for is authorization, not authentication. Django's built-in authorization system is fairly crude, as you've discovered. You'll need something like django-authority if you want a more complete solution.
The auth module is typically used to cover authentication cases.
Gives you groups (Institutions), Users (Individuals) and permissions.
Using these features you can perform checking if a user is a member of a group or owns a doc before allowing them to see or edit the doc.
http://docs.djangoproject.com/en/dev/topics/auth/
If you need to go beyond the typical use case, supporting LDAP for example, then you can look at writing your own authentication backend.
http://docs.djangoproject.com/en/dev/topics/auth/#other-authentication-sources
In general, if you need to attach more information to the builtin User model, you would create new model which subclasses models.Model (not User), and identify it in settings as AUTH_PROFILE_MODULE. You can get the appropriate instance of your model from a user by calling user.get_profile(). (see http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users).
This is generally useful for adding extra fields to User such as address, contact information, etc. While it would be possible to use this for your authentication needs, you'd most likely be better off using the built in groups, or a more comprehensive solution like django-authority as others have mentioned. I've included this answer only because it seems to be what you were asking for (a way to attach a class to User), but not really what you need (authorization).

Categories

Resources