I am using WMD editor in the django admin. I have written a simple parser (regex mostly) so I can catch specific tags in the markdown and insert HTML accordingly. My problem is that I need access to the Django object itself.
Currently I'm overriding Model.save() and calling Model.process_markdown()
def process_markdown(self):
p = re.compile("\[\[\s*(?P<tag>image):(?P<id>[\d,]+)\s*\]\]")
processed = p.sub(partial(render_markdown, self), self.body_markdown)
return markdown.markdown(processed)
The result is then saved into a Model.rendered field on my model. If you notice I have a render_markdown function being called. Thats stored in a file called util.py in my app and does all the real work.
Everything is working but this seems like there should be a better way. I know I can tie into markdown for custom tags and do this a cleaner but I have to beable to access the django object and I as I reference related inline objects. As far as I can tell there is not a way for me to do this.
Is there a better way to organize this?
Beware that markdown allows HTML to be tunneled through. If you do this, you probably want markdown(html, safe_mode='escape') If you're allowing untrusted sources to insert .body_markdown, you will need to sanitize that input via something like bleach: http://pypi.python.org/pypi/bleach
Related
I'm new to Django and coming from Rails, so that may explain my odd questions below:
I have a main layout that has a sidebar that lists the latest updates to the site. That main layout is used for every page in my webapp so every template that is created extends main.html.
For the latest updates section, I just want to get the last 5 updates from posts to the web app every time a page is rendered. I thought about making the sidebar do this through an ajax call once the page is loaded, but I thought this may not be my best option.
I also considered creating a tag to do this for me and then just calling the tag inside of main.html. This is simple enough, but I'd have to write a lot of HTML inside of the tag code, which seems to be a little annoying (a lot of string appending and such, unless I'm wrong and there is a better way?)
I have read about Context Processors. This seemed to be exactly what I wanted, but it appears this may cause another issue where I have to pass a context_instance to every single render_to_response? This appears to be a lot of code repeat and I'm trying to avoid that if possible. Is there a way to just make render_to_response always take the RequestContext object without always having to specify it?
Are there any other ways to achieve having some code run for every view and eliminate the need to always pass data to a view?
Django 1.3 added the render shortcut which is the same as render_to_response but with RequestContext automatically used.
Templates is a appropriate place for this: the variant with custom tag and template inheritance is simple and convenient. To avoid string appending use mini-template just for your tag: it is called inclusion tags.
I would definitely go for the Ajax call, it is as simple as to create an small view which queries the model for the 5 latest posts, serializes them into json or xml data, and returns them in your HttpRequest object.
You can use direct_to_template instead of render_to_response.
I've been working with django over past couple of months. It seems that if I need some new value in a template, the only way to accomplish that is to pass it through the view function directly or an object that can be somehow used to retrieve that information.
What if I want to "PULL" information from the template? Consider the following scenario. I have a template "template1" associated with Application1. Suppose in one column of this template, I want to import information from second application "Application2". Currently the only way I know is to use the Application1's view functions to pull that info from Application2. For every new application I need to change my Application1's view function. So in case I want to keep adding information from different applications(2,3,4 etc), I would need to keep on changing the view function of Application1. This could get cumbersome.
So what I want is something like Wordpress's widget function or Joomla's module type functionality. Simple plug and play, that can "pull" the information from different sources(apps). Does django have something of this sort built-in?
Ah, you have encountered one of the fundamental differences between Django (and most Python templating frameworks) and WordPress (and most PHP frameworks). PHP has a huge global name space that can be accessed from pretty much any place in the page creation process. Python, on the other hand, does not. Many of us consider this to be a Good ThingĀ®.
However, there are times when you wish you had a few more globals for use in your templates. To accomplish this, what you want is a context processor. This is a routine that returns a dict that is automatically included whenever you use RequestContext() to build your call to your template.
You may also want to look at {% expr ... %}. It allows you to break out of the "chains" of the deliberately weak Django templating engine.
Suppose I have a Django app named "blog".
There's a model called Post and I have an external API call that returns the list of the most popular posts in a given time, e.g., the Google Analytics API.
My question is: Where is the expected place that I should place the code that makes the call to the external API, parses the id from each post, query the database and sort the list of models accordingly?
I don't think that it should live in the Manager or in a templatetag. Any tips or suggestions?
Thanks in advance!
EDIT: The desired result might be need in several places across the project, so if I place the code in view, I'll have duplication.
It should be done in a view, or better, if your view code is getting cluttered, put it in a helper module.
import util
def view(request):
util.process_post_rankings(request.user.id)
# ... write additional logic and render to template
However, be cautious with relying on external apis to render a page to your user. Things might go wrong, take an awful lot of time, API might not respond etc... Better to do that asynchronously with Javascript, and update the page when data is ready.
This sounds like it should be done in a View, because then you will be returning to a template with all the required context.
I am using the standard User model (django.contrib.auth) which comes with Django. I have made some of my own models in a Django application and created a relationship between like this:
from django.db import models
from django.contrib.auth.models import User
class GroupMembership(models.Model):
user = models.ForeignKey(User, null = True, blank = True, related_name='memberships')
#other irrelevant fields removed from example
So I can now do this to get all of a user's current memberships:
user.memberships.all()
However, I want to be able to do a more complex query, like this:
user.memberships.all().select_related('group__name')
This works fine but I want to fetch this data in a template. It seems silly to try to put this sort of logic inside a template (and I can't seem to make it work anyway), so I want to create a better way of doing it. I could sub-class User, but that doesn't seem like a great solution - I may in future want to move my application into other Django sites, and presumably if there was any another application that sub-classed User I wouldn't be able to get it to work.
Is the best to create a method inside GroupMembership called something like get_by_user(user)? Would I be able to call this from a template?
I would appreciate any advice anybody can give on structuring this - sorry if this is a bit long/vague.
First, calling select_related and passing arguments, doesn't do anything. It's a hint that cache should be populated.
You would never call select_related in a template, only a view function. And only when you knew you needed all those related objects for other processing.
"Is the best to create a method inside GroupMembership called something like get_by_user(user)?"
You have this. I'm not sure what's wrong with it.
GroupMembership.objects.filter( user="someUser" )
"Would I be able to call this from a template?"
No. That's what view functions are for.
groups = GroupMembership.objects.filter( user="someUser" )
Then you provide the groups object to the template for rendering.
Edit
This is one line of code; it doesn't seem that onerous a burden to include this in all your view functions.
If you want this to appear on every page, you have lots of choices that do not involve repeating this line of code..
A view function can call another function.
You might want to try callable objects instead of simple functions; these can subclass a common callable object that fills in this information.
You can add a template context processor to put this into the context of all templates that are rendered.
You could write your own decorator to assure that this is done in every view function that has the decorator.
I am building a multi-user web application. Each user can have their own site under my application. I am considering how to allow user to modify template without security problem? I have evaluated some python template engine. For example, genshi, it is a pretty wonderful template engine, but however it might be dangerous to allow user to modify genshi template. It have a syntax like this:
<?python
?>
This syntax allow you run whatever you want python can do. I notice that it seems can be shutdown by passing some parameter. But there are still a lots of potential problems. For example, user can access build-in functions, and methods of passed variables. For example, if I pass a ORM object to template. It might contain some method and variable that I don't want to allow user touch it. May like this:
site.metadata.connection.execute("drop table xxx")
So my question is how can I allow user to modify template of their site without security problems? Any python template engine can be used.
Thanks.
Jinja2 is a Django-ish templating system that has a sandboxing feature. I've never attempted to use the sandboxing, but I quite like Jinja2 as an alternative to Django's templates. It still promotes separation of template from business logic, but has more Pythonic calling conventions, namespacing, etc.
Jinja2 Sandbox
Look at Django templte engine. It does not support execution of arbitrary python code and all accessible variables must be passed into template explicity. This should be pretty good foundation for building user-customizable pages. Beware that you'll still need to handle occasional syntax errors from your users.
In rails there's something called liquid. You might take a look at that to get some ideas. Another idea: at the very least, one thing you could do is to convert your objects into simple dictionary - something like a json representation, and then pass to your template.
The short answer is probably "you can't".
The best you can probably do is to trap the individual users in virtual machines or sandboxes.