Plugins for pyramid (themes, views etc) - python

Ok here is the problem in brief. I do have a pyramid setup that does start to look like a cms.
I have as base models: [accounts, pages, errors, menus, configs]
It works pretty well but I do have a little problem with something. Currently i'm using git and on some branches I do have different templates and on the master branch I do my change to the core.
I'd like to be able to install themes instead. Themes would be a collection of template files/static file(css/js).
That can be achieved with entry_points and my config view can look them up and display a list of installed themes. That so far can be done.
Being able to switch different themes on the fly would be a very good start so I wouldn't have to fork my projects only for new themes.
The second problem is that theses sites requires different content. For example, one would require "Question" and the other "Products"
So I have this idea in mind
class TemplatePlugin(PyramidPlugin):
template_path = ''
static_path = ''
def register(self, config, app):
'''Inject the plugin in the application... how I'm not sure yet'''
def unregister(self):
'''unregister the plugin if something is needed'''
def (before/after)_(request/newapp...)(self,...):
'''do some stuff for some events most are optional'''
And a different plugin for models
class PyramidPlugin(pyramid_plugin):
def register(self, config, app):
'''add routes,
add view handlers (view_config)
add models acl to the acl list
'''
# other functions similar to the above class to handle events
My biggest problem is how does it find files. I will have to do some test but i'm worried about translations, and file path.
How does it works through entries points is still a mistery to me. Will plugins use babel translations... can I use my babel translation in my template plugins? When an entry point is loaded..current dir is the dir of the project or the dir of the entry point? I believe I can easily get the path with distribution but I'm not sure what is the right way to do all this... I feel like i'm getting in a whole new land filled with mines.

In Pyramid you can pick templates at run-time using render_to_reponse function. But if you want a more cooked solution, you might get inspired by Kotti, a Pyramid CMS that already has support for addons and look and feel customization with 'Babel' for internationalization. In order to use another 'theme' you have to write another package with some templates and static assets following the convention Kotti uses and then you activate the package in the .ini configuration file.
To understand how Kotti achieves this, you should start following the code path from this line
In any case, Kotti makes some assumptions about how the Pyramid application is configured, such as SQLAlchemy for storage, formencode for form generation or traversal to map views to resources, so YMMV. Pyramid itself is unopinionated about the way you do this.

Related

Proper project structuring

I've recently started as the sole developer on a Django project. I'm currently working on updating an endpoint to including validation for incoming PDF documents.
The simple validation function follows:
def is_valid_certification(stream: BytesIO) -> bool:
pdf = PdfFileReader(stream)
page: PageObject
for page in pdf.pages:
if page.extractText().find(<search string>) != -1:
return True
return False
My question is, where is the most pythonic place to store this bit of code? Keeping all the logic within the POST handler seems messy and it's not generic enough to be considered a utility.
You can follow the fat model concept and have this function in the model that is responsible for this.
You could also create a services.py file in your app for functions and services that are specific to that particular app.
Any functions that are generic to the the project can go into the app named after project
I don't think there's a single correct answer for this, but I find that as my views.py files grow, the best way to keep them lean is just to move the business logic to other files as makes sense. Code doesn't necessarily have to be reusable to be abstracted; sometimes you just don't want a file to be 2,000 lines long, and you want a logical separation of functionality (e.g., views.py really just focuses on collecting data for rendering and all the heavy lifting is done in other modules).
For larger apps, especially with a lot of admin site customization, I'll often have the following files for a single app:
admin_form_processing.py
admin_forms.py
admin_inline_forms.py
admin_utils.py
form_processing.py
forms.py
urls.py
utils.py
views.py
some_file_that_processes_view_logic_1.py
some_file_that_processes_view_logic_2.py
etc.
I also often create an app called core or utils that has no urls/views but contains modules for general utility functionality (e.g., form_utils.py for form-related utilities that are used across multiple apps).

django package organization

I plan to build my project in Django framework. However, I noticed that all Django packages have models.py file. Now, let say I have a set of general purpose functions that I share between several apps in the project and I plan to put these functions definitions in a separate package (or app for that matter?). So, should I create an app "general" and copy-paste these functions into the models.py file? Or can I just create a general.py file in the "general" app directory and leave models.py empty? What is the "Django" way to do that?
Thanks.
models.py file is used to define the structure of database. So you should leave it for defining your database entries. You can make an app named generals and put general.py in that app, and from there you can use it by calling it in any app.
I usually create a utils.py file under my main app that is created from the django-admin.py when starting the project.
I plan to put these functions definitions in a separate package (or app for that matter?)
Before you decide to make this an app (and if you do decide to make it an app), I recommend you take a look at James Bennet keynote on Developing reusable apps and hist post on laying out an application. From one of his slides:
Should this be its own application?
Is it orthogonal to whatever else I’m doing?
Will I need similar functionality on other sites?
Yes? Then I should break it out into a separate application.
If you're cramming too much functionality in one single general purpose app, it might be better to split your general purpose app into multiple reusable apps.
Going back to your original question, Django is expecting a models.py file in every app. So you must have the file even if it's empty.
Inside your models.py, you should only have the application’s model classes. So, you wouldn't be following a best practice if you put inside models.py some miscellaneous code you want to reuse.
From the laying out an application post I mentioned before:
At the application level, I usually drop in a few more files depending on exactly what the application is going to be using:
If the application defines any custom manipulators, I put them in a file called forms.py instead of in the views file.
If there are multiple custom managers in the app, I put them in a file called managers.py instead of the models file.
If I’m defining any custom context processors, I put them in a file called context_processors.py.
If I’m setting up any custom dispatcher signals, they go in a file called signals.py.
If the application is setting up any syndication feeds, the feed classes go in a file called feeds.py. Similarly, sitemap classes go in sitemaps.py.
Middleware classes go in a file called middleware.py.
Any miscellaneous code which doesn’t clearly go anywhere else goes in a file or module called utils.
All of this does not answer directly your original question:
can I just create a general.py file in the "general" app directory and leave models.py empty?
But I hope this gives you additional information to make a decision that better fits your project and requirements.

link django with modules of other applications

I would like to link django with an existing python application, reusing the modules, the classes and some configurationfiles that were defined in this application. All modules reside in the ./bin directory of this application. In fact the application is a forecasting system, and django will be used as the frontend to visualise the results.
The current directory structure looks like this.
./application/bin/module1.py
/module2.py
/config.txt
/datadir/...
/webresults/run1/myfig.png
/run2/myfig.png
/...
./django/manage.py
/project1/urls.py
/settings.py
/wsgi.py
/app1/views.py
/models.py
/forms.py
/...
/templates/base.html
/showResults.html
/...
An apacheserver is set up to serve static pages and images from the directory ./application/webresults/ and django pages from /django/project1/wsgi.py.
For the moment I have copied all relevant modules from /application/bin/ to django/app1/ so I can reuse them eg. in views.py and models.py. With respect to maintenance of the system not an optimal solution.
So I am looking for a more elegant solution to solve this. Some of the things we would like to achieve:
moving around the backendapplication is harder than moving around django instance, so preferable django is relocated (it was not coded in the most efficient way :-))
reuse classes of application in django
reuse models of django in the application
reuse SQL_objectmapping in the application
use one configfile for settings relevant to both django and the application
The solution we are thinking of, would be to merge all djangocode into /application/bin/ and remap the djangopath in apacheconfiguration
./application/bin/manage.py
/module1.py
/module2.py
/project1/urls.py
/settings.py
/wsgi.py
/app1/views.py
/models.py
/forms.py
/...
/templates/base.html
/showResults.html
/...
Are there any recipes on how this could be handled? Any advice appreciated.
There's nothing wrong with tossing your Django project within another module. So long as your PYTHONPATH's are setup correctly, and your WSGI is configured right, everything should work normally.
My only comment would be that, tautologically, "separate things should be separate."
When I have similar problems, I usually create a simple UNIX socket server (using Tornado), that Django can communicate with for API calls, etc.
If I need to expose the functionality of the socket server, I'll throw in a cheap WSGI server (again, with Tornado) that serves up requests, and stick it under a different subdomain within my hosting configuration.
I think my original question was not very clear. Since then I stumbled upon some other answers and pages that helped me , mainly on how to reuse django functionality in external modules and applications.
http://www.b-list.org/weblog/2007/sep/22/standalone-django-scripts/
why 'list index out of range' in my django code;
https://docs.djangoproject.com/en/dev/ref/models/options/#app-label
With this information I managed to access my models (in apps-subfolder) from the pythonscripts on the root of the application (eg. module1.py).
In short the code to access app1.models.Mymodel from module1.py looks now like this :
os.environ['DJANGO_SETTINGS_MODULE'] = 'project1.settings'
from django.core.management import setup_environ
from project1 import settings
setup_environ(settings)
import app1.models
class MyChildmodel(app1.models.Mymodel):
class Meta:
app_label = 'app1'
def myfunction():
....

Django and MVC(MVT) layout

Im coming from using other MVC based frameworks, and going into Django, it seems a little awkward to what im used to. For example, in other MVC based frameworks. my layout might be like so:
root:
- config (houses the config files (like settings), url.conf, db connections, etc.)
- controllers (houses the main logic of each section of the site. The middle ground between views and models)
- models (handles all the data to be validated and anything that interacts with the database. declares the DB structure. each model a class, each attribute a db field. in django, a template?)
- views (the html displayed to the end user, put together by the controllers)
- tests (all the tests)
- plugins (3rd party apps you install into yours.)
- uploads (user uploaded files)
- public_html (the actual public facing files)
-\ css|js|img (the various static file types for page manipulation)
-\ index.html
That is what im used to, and it seems like django does things very differently. Where before if I had a poll app i would have:
controllers/PollController.py
models/Poll.py
views/poll/index.py
and that would create the poll table in the db. But in Django, how would I do this? Is this an acceptable layout? From what I have read, the above would be more like this:
root:
- project (this would be the main app, and what glues everything together)
--/ settings.py
--/ urls.py
--/ templates/
- apps
-/ Poll
--/ models.py (i would have no Poll.py model, so it would all go in here)
--/ urls.py (any url.conf specific to this model would go in here)
--/ templates/ (the various views for this app)
while this does makes sense in some ways, it just feel alien to me. Is there any benefit to this type of layout over a traditional mvc layout described in the first example? Is there another preferred layout beyond this? The purpose of this 'project' is that the core will be a basic framework for my own use and I have a few different 'apps' that i will create for each use of this framework. in the old version each application would just extend the main one by being a plugin in that directory.
As a background note, most of my experience is in php and the various frameworks from that worls (cakephp, yii, mostly), if that makes a difference. This will be my first main project in python/django. i just want to get it right.
The biggest benefit is that apps are modularized. You can remove your Poll application by deleting one directory instead of hunting through several directories deleting each piece. The flip side is if you found a Poll application somewhere that you wanted to use you can just drop in the one folder and you're good to go.
If you approach the idea of a site being a conglomeration of several individual and mostly distinct "apps" with some glue to hold them together then this organization makes much more sense.
Is there any benefit to this type of layout over a traditional mvc layout described in the first example?
Yes.
What you appear to be calling "Traditional MVC" is just another framework. It's not magically better or more right. It's just different.
Is there another preferred layout beyond this?
There are probably hundreds of ways to do this. Django chose one that fits nicely with Python and web applications.
i just want to get it right.
Then do this.
Discard your preconceptions left over from other things you've done.
Start fresh and empty with Django like a complete beginner.
After you've learned your 6th framework, you can then (and only then) compare and contrast the six frameworks you've learned. Until you've learned six, each one has to be taken as new, complete, different and unique.
Don't compare and contrast yet.
Just take Django as Django and do things the Django way.
(For more metaphorical advice, read about the music of Django Reinhardt; he had a unique view and a unique approach to the guitar.)
Notes
root # doesn't mean anything
config -- Doesn't exist.
controllers -- Doesn't exist.
models -- A Python module with the class definitions for the persistent objects. Maps to RDBMS schema. Can have model-specific tests.
views -- A Python module with view functions that respond to requests and create responses.
test -- A Python module with View-specific and template-specific tests.
plugins -- Doesn't exist.
uploads -- Runtime, not development of the application.
public_html -- Does not exist.
css|js|img -- Static "Media" files. Runtime, not development.
index.html -- Does not exist.
Stuff you omitted
templates -- your HTML template pages, used by the view functions.
admin -- admin bindings for the default admin site. Relies on modules and forms.
forms -- form definitions; these are classes that produce forms used for input validation.
urls -- mappings from URL paths to view functions.
settings -- module with default database configuration, middleware, etc.

How do you manage your Django applications?

I just wanted to try to build a project with django. Therefore I have a (basic) question on how to manage such a project. Since I cannot find any guidelines or so on how to split a project into applications.
Let's take a kind of SO as an example. Which applications would you use?
I'd say there should be the applications "users" and "questions". But what if there was a topic system with static articles, too. Maybe they also could receive votes.
How to build the apps structure then? One app for "questions", "votes" and "topics" or just one app "content"?
I have no idea what to do. Maybe it's because I know not very much about Django yet, but I'm interested either...
There aren't hard-and-fast rules, but I would say it's better to err on the side of more specialized applications. Ideally an application should handle just one functional concern: i.e. "tagging" or "commenting" or "auth/auth" or "posts." This type of design will also help you reuse available open source applications instead of reinventing the wheel (i.e. Django comes with auth and comments apps, django-tagging or django-taggable can almost certainly do what you need, etc).
Generic foreign keys can help you decouple applications such as tagging or commenting that might be applied to models from several other applications.
You should try and separate the project in as much applications as possible. For most projects an application will not contain more than 5 models. For example a project like SO would have separate applications for UsersProfiles, Questions, Tags (there's a ready one in django for this), etc. If there was a system with static pages that'd be a separate application too (there are ready ones for this purpose). You should also try and make your applications as generic as possible, so you may reuse them in other projects. There's a good presentation on reusable apps.
Just like any set of dependencies... try to find the most useful stand-alone aspects of the project and make those stand-alone apps. Other Django Apps will have higher level functionality, and reuse the parts of the lowest level apps that you have set up.
In my project, I have a calendar app with its own Event object in its models. I also have a carpool database set up, and for the departure time and the duration I use the calendar's Event object right in my RideShare tables. The carpooling database is calendar-aware, and gets all the nice .ics export and calendar views from the calendar app for 'free.'
There are some tricks to getting the Apps reusable, like naming the templates directory: project/app2/templates/app2/index.html. This lets you refer to app2/index.html from any other app, and get the right template. I picked that one up looking at the built-in reusable apps in Django itself. Pinax is a bit of a monster size-wise but it also demonstrates a nice reusable App structure.
If in doubt, forget about reusable apps for now. Put all your messages and polls in one app and get through one rev. You'll discover during the process what steps feel unnecessary, and could be broken out as something stand-alone in the future.
A good question to ask yourself when deciding whether or not to write an app is "could I use this in another project?". If you think you could, then consider what it would take to make the application as independent as possible; How can you reduce the dependancies so that the app doesn't rely on anything specific to a particular project.
Some of the ways you can do this are:
Giving each app its own urls.py
Allowing model types to be passed in as parameters rather than explicitly declaring what models are used in your views. Generic views use this principle.
Make your templates easily overridden by having some sort of template_name parameter passed in your urls.py
Make sure you can do reverse url lookups with your objects and views. This means naming your views in the urls.py and creating get_absolute_url methods on your models.
In some cases like Tagging, GenericForeignKeys can be used to associate a model in your app to any other model, regardless of whether it has ForeignKeys "looking back" at it.
I'll tell you how I am approaching such question: I usually sit with a sheet of paper and draw the boxes (functionalities) and arrows (interdependencies between functionalities). I am sure there are methodologies or other things that could help you, but my approach usually works for me (YMMV, of course).
Knowing what a site is supposed to be is basic, though. ;)

Categories