Django: Implementing a nested, reusable component design - python

I'm working on a big social networking app in Django where I expect to use certain front-end components many times, and often with functionality designed in such a way that custom components contain other custom components, which might contain yet smaller subcomponents (ad infinitum). All of these components are typically dynamic generated. I'm trying to figure out the best way to architect this in the Django framework, such that my components are easy to maintain and have clear programming interfaces. Relying heavily on global context would seem to be the opposite of this, however, I can see advantages in avoiding redundant queries by doing them all at once in the view.
Custom inclusion template tags seem like a good fit for implementing components, but I'm wondering, do highly nested template tags can create performance issues, or does the parsing architecture prevent this? What is the best way of making it self-documenting at the view level what context is needed to render the main page template, custom tags and all? I'm imagining it to be a minor nightmare to try to properly maintain the code to set up the template context. Lastly, what is the best way to maintain the CSS for these components?
Feel free to suggest other recommended approaches for creating a nested-component design.

The solution I've decided on so far is to go ahead with using an inclusion tag library as my set of reusable components. I'm sticking as much as possible to setting up all queries in my view code, and passing them in pre-setup in my context--no functions that generate new queries in templates or tag library code. The inclusion templates contain all of the markup for the item, and the styles go into the main site stylesheet, keeping my classes as generic and reusable as possible, following the guidelines of SMACSS. I refactor components into inclusion tags only as DRY requires.
I initially made my inclusion tag functions explicitly take the parameters used by the tag template, such that:
Page template
<div>{% my_tag param1 param2 %}</div>
Tag library
#register.inclusion_tag('myapp/tagtemplates/my_tag.html')
def my_tag(param1, param2):
return {'param1': param1, 'param2': param2}
my_tag.html
<div>Blah: {{ param1 }}</div>
<div>Blip: {{ param2 }}</div>
...and obviously the view sets up the context.
But I decided instead to use the takes_context parameter to avoid explicitly defining the parameters in the tag library. Too much repetition for not enough payoff in documentation. So far, my components are simple enough that the dependencies are pretty clear from inspection of the tag template. I worry that this might not be acceptable with complicated nested components, but I can always make my tag library functions verbose, where they need to be.
I'm not entirely pleased with this setup from a maintenance standpoint. I don't like that I will have to manually track what context data is no longer needed. I don't like the fact that my CSS classes will have to be carefully named to avoid clashes.
I am still open to new solutions, because I'm not sure that what I've decided really is a best practice.

It is an interesting problem. Ideally you should pull all the components from database before rendering. But looking at hierarchy, making template tags makes sense. These template tag will pull appropriate data. Assume for the purpose of this problem that database query gets cached due to search locality.

Related

Django: allow safe html tags

Im looking into XSS with various frameworks and CMS and whether they provide methods in protecting against it (not just programmaticly avoiding the situation).
I know that in Djangos templating language you can specify a variable as |safe I want to be able to allow actually safe html tags so the user can format text (simple things like etc), but strip such things as , onload attributes etc.
I would like to know whether Django recommends a method in doing this, not just using Python. I hope this makes sense
Jason
One of the core concepts of Django is that it's Python, and any Python lib should be usable with Django. They won't recreate the wheel unless there is good reason to. I believe HTML scrubbing/sanitizing is one of the things they've decided not to recreate.
BeautifulSoup is the python library you want to look into for any scrubbing/sanitizing though.

Pyramid: simpleform or deform?

For a new (Python) web application with the Pyramid web framework, I'd like to use a form binding and validation library and so far found simpleform and deform. Does anyone have experience with these, and can tell me why I should pick one or the other? I am not using an ORM, just POPO's so to say.
I think I would prefer the easiest for now.
I've not had extensive experience with either, but so far this is what I've learned.
They both use colander (which I very much like) for definition and validation of forms. In my opinion what really sets them apart is their rendering mechanisms. In this regard, deform is the most straightforward in the sense that it allows you render the whole form by just doing form.render() in your template. On the other hand, with simpleform you must render each field manually. This could be either a good or bad thing depending on what you need.
A drawback with simpleform is currently there is no clear way to handle sequence schemas in templates.
edit: Also, in my opinion, deform has better documentation available.
I haven't used simpleform yet, but I have been using deform for a project I'm currently working on. deform allows you to render templates from a colander schema, which is very handy. Also, if the schema is violated you can simply call ValidationFailure.render() (after catching the ValidationFailure exception) and a message that you can customize is rendered with the form. I'm currently grappling with the choice between rendering the entire form and rendering it piece by piece. It would be really nice if you could group components together for rendering.
Though it's a third alternative, but have you considered ToscaWidgets2?
From a quick glance on simpleform and deform, it seems to me that Toscawidgets2 is the golde middle between those two in case of features and simplicity.
There's even a tutorial for using it with Pyramid, just drop the database part and supply the form values as a dict.
For your information, deform is used by :
Kotti : http://kotti.readthedocs.org/en/latest/
Substance D : https://substanced.readthedocs.org/en/latest/

Since Django discourages passing arguments to functions in templates, what is encouraged instead?

I understand that in Django, the template language is purposely neutered to prevent too much computation in display code. It means that, ideally, for every situation where users might feel compelled to do computation, there's a more proper alternative. Either a tag or filter that does the trick, or something hopefully straightforward in the view. Any annoyances that don't fit into here are hopefully rare.
But I've found a common case that is rather annoying, and either Django has a better way to do this that I haven't thought of, or they ought to see the light here and move the line a little bit on computing within a template in a near future release (as they did with if statement parameters, for instance):
I have a queryset of items. I need to display them somehow, but what I display depends not only on the state of the object, but also other independent things (usually who is logged in). So adding a function to the model won't help.
What I've been doing so far is turning the queryset into a list or tree structure (depending on the task), and adding a "view_extra" attribute to each one. view_extra is a dictionary where I generally stick in values that are dependent on things like who is logged in. Apart from being a hassle, it also destroys the laziness of the queryset. I guess I could go so far as to make a generator, but obviously this is not what the Django developers had in mind for us to do.
I should probably try queryset annotation more, but I don't know how well that would work in some more complicated cases. Plus, no good in a tree or list-within-list structure scenario (queryset of items with members that are further querysets I need to iterate over).
I could register a filter, (as suggested here django template system, calling a function inside a model) but that is an abuse of filters, right? They are meant to transform text and maybe data, not to be a specific-purpose replacement for something the developers deliberately tried to get us not to do.
Any "proper" way to do this that I don't know about? Am I off base here by suggesting that this is a deficiency of Django's templating system as it stands?
I don't see why creating a custom tag or filter is an 'abuse'. As far as I'm concerned, that's exactly what they're for, and I use them for that all the time.
Maybe Jinja templates would be a good alternative to using Django's templating system in this instance. Apart from the important fact that Jinja allows you to use some level of logic in your templates, Jinja templates and Django templates are almost identical.
This example code taken directly from the Jinja documents looks like it might be the kind of thing you're trying to achieve.
{% for comment in models.comments.latest(10) %}
...
{% endfor %}
To integrate Jinja with Django, you could look at Coffin

Using classes for Django views, is it Pythonic?

I'm currently learning Python and coming from a strong C# background. I keep hearing about doing things in a Pythonic way to take advantage of the dynamic nature of the language and some of it I get and some I don't.
I'm creating a site with Django and my approach to views is to use classes. My current thinking is to have a base class that has some stuff about the template and the model to use. This will have a default funky 404 type page with site search and stuff on then base all the other pages off this. So each area of the site will have its own EG News and all the model related functions and filtering will be in that class with a further class on top of that for HTML or AJAX requests. So you would have something like this:
\site\common\ViewBase
--\news\NewsBase(ViewBase)
--\news\HtmlView(NewsBase)
--\news\AJAXView(NewsBase)
URLs would be mapped like http://tld/news/latest maps to site.news.htmlview and http://tld/news//to/ will be also be mapped site.news.htmlview but the class will figure out what to do with the extra params.
This is pretty much what I would do in C# but the Django tutorial only shows using methods for views, making me wonder if this is not a very pythonic solution?
Thoughts?
Edit: After S.Lott comment about thread safety, Is it better to leave the functions as they are and have them create an instance of a class and call a method on it?
What I am looking for is a place to put common code for each section of the site for filtering the model, authentication for the site, etc
Certainly there's nothing wrong with using a class for a view, provided you route the URL to an actual instance of a class and not just a class directly.
The Django admin does exactly this - look at the source code in django/contrib/admin.
The advantage of classes is that they are much easier to customize, for example you can add hooks for permission checking.
There is a proposal to move all existing generic views over to classes, it was supposed to get into 1.2 but failed to meet the deadline.
As the above poster points out, be very careful about handling instance variables - if you look at the admin classes, you see the request being passed to the various methods instead of relying on "self".
Setting aside other concerns (such as thread-safety issues), it feels like there's a real possible danger here to cross the bright lines between Model / View / Template.
Or maybe it feels like a replacement for url dispatching (not that there's anything wrong with that :-). I'm not sure, but it just feels slightly off.
While class-based views are useful, inheritance may not be the right tool for this particular job. Helper functions and decorators are two great ways to factor out common code from your views. They also tend to be be more familiar/natural to other (python) coders who might work on your code.
I'm not sure what the best approach is in your case as I don't know how much you ultimately want to factor, just keep in mind that there are other ways to factor in python besides inheritance.
p.s. kudos for seeking out a pythonic solution.

Untrusted templates in Python - what is a safe library to use?

I am building a library that will be used in several Python applications. It get multilingual e-mail templates from an RMDBS, and then variable replacement will be performed on the template in Python before the e-mail is sent.
In addition to variable replacement, I need the template library to support if, elif, and for statements in the templates.
I use Mako for most my projects, and also looked at Tempita as it doesn't provide a lot of features I don't need.
The concern I have is untrusted code execution - can someone point me at a template solution for Python that either does not support code execution, or will allow me to disable it?
From the Django book:
For that reason, it’s impossible to call Python code directly within Django templates. All “programming” is fundamentally limited to the scope of what template tags can do. It is possible to write custom template tags that do arbitrary things, but the out-of-the-box Django template tags intentionally do not allow for arbitrary Python code execution.
Give Django templates a try. It's a little tricky to set up outside of a Django app -- something to do with DJANGO_SETTINGS_MODULE, search around -- but may be trusted.
Have you checked out Jinja2? It's pretty much what you're talking about, and it's a great mix of powerful while keeping things simple and not giving the designer too much power. :)
If you've used Django's template system, it's very similar (if not based off of?) Jinja.

Categories

Resources