views:

56

answers:

4

I have a simple Blog model with a TextField. What is the best way to save links in the TextField ?

1) Saving link in the database in this form: http://www.example.com and then using some filter in the template to trasform it in form:

<a rel="nofollow" href="http://www.example.com&gt;http://www.example.com&lt;/a&gt;

2) Saving link in the database directly in this form:

<a rel="nofollow" href="http://www.example.com&gt;http://www.example.com&lt;/a&gt;
A: 

I would save the URL itself, and append the tag and parameters at the output. In my opinion it is better to separate the storage, processing and presentation of the data, to accommodate future changes easier (for example when in a future version the URL get used for something entirely other like automated downloads).

Rudi
A: 

You could use a URL field (or a TextField, of course) and then render it in a template.

<a rel="nofollow" href="{{ url }}">{{ url }}</a>
Olivier
I am talking about link in the TextField ;)
xRobot
Well, I suggested that you use a URL Field instead of a Text field. Why use the TextField in the first place? Beside, my answer is exactly the same even if you want to use a TextField.
Olivier
The OP is talking about the links included in a blog post. I don't think there is any (good) way to have an arbitrary number of URLFields depending on how many links are in a particular post.
Chris Lawlor
A: 

use the second alternative, and after use safe to escape html code

eos87
+1  A: 

Assuming you are talking about how to save links (or any HTML formatting really) that you are including in your blog posts, not standalone links (like for a blogroll):

You might want to think about adopting some sort of markup language like Markdown or BBCode. You'd then store the blog post in the pure markup syntax, and provide a method (like blog.get_post()) that would parse the stored markup and return HTML. You'd then use the safe filter in your template to avoid escaping the HTML.

Even better, to avoid parsing your markup on every request, cache it in the database. Add a TextField called something like text_html to your Blog model. Override your Blog model's save method to parse the markup into HTML and save the HTML to the text_html field.

Then when you want to render the blog post in a template, you can use {{ post.text_html|safe }} without having to parse your markup each time.

So your Blog model might look like this (only text field shown for clarity)

import markdown

class BlogPost(models.Model):
    text = models.TextField()
    text_html = models.TextField(editable=False) # don't want to see this in Admin

    def save(self, force_insert=False, force_update=False):
        self.text_html = markdown(self.text)
        super(BlogPost, self).save(force_insert, force_update)

To make things simpler on the data entry side, you could also add in a nice javascript editor - like the one I'm typing this answer in right now.

Chris Lawlor
2 textfield for the same information ? is a good approach ?
xRobot
I think so. It's a denormalization - trading off a little DB space for faster access (don't have to parse markdown for every request). DB space is usually a lot 'cheaper' than CPU time. This is also the approach recommended in James Bennett's book Practical Django Projects. I've used it with success in the past.
Chris Lawlor
Coincidentally, the example in the book was even for a blog project.
Chris Lawlor