Home » Odeon Blogs »

Liviu, Agile Bear

Local server on VirtualBox guest OS

Are you using Parallels? Check out this post.

VirtualBox is another great virtualization software, especially useful for Ubuntu and Windows users.
As web developer you often need to change OS for cross browser testing
and it's best to do it before pushing your code to the production
server.

You can use your Host's dev server in the Guest OS, without needing to syncronize all your files between the two.

Assuming your are starting the server using the localhost or 127.0.0.1 IP address you can easily access it.

Just open up a Command shell on Guest and type

  1. ipconfig

From the information in there you need the gateway's IP. so if you type that in the Guest's browser it will open up the Host's dev server.

For django, dont forget to add the port, if you are using other than 80, just like you open it in the Host's browser.


Category: Virtualization


Tagged as: apache dev devserver django guest host parallels server virtualbox

Leave a Comment

Local server on Parallels guest OS

Are you using VirtualBox? Check out this post.

Parallels is a great virtual machine software, especially for MacOS where the RAM usage is less than half of the VirtualBox load.
As web developer you often need to change OS for cross browser testing and it's best to do it before pushing your code to the production server.

You can use your Host's dev server in the Guest OS, but you need to know 2 things:

1. The Host's LAN IP

Within Parallels Guest OS you can access the Host using it's LAN IP.
To find what is your LAN IP type the following in a terminal:
  1. # linux/macos
  2. ifconfig

  3. # windows
  4. ipconfig

2. Start your Host's dev server on the LAN IP

Starting your local server is different from one software to another.

For Apache, you will need to edit your httpd.conf and restart it.

For Django, you can just run (where XXX.XXX.XXX.XXX is your LAN IP)
  1. ./manage.py runserver XXX.XXX.XXX.XXX:8000

Now you can open up Parallels Guest OS and browse to the Host's IP and you will see your dev server.


Category: Virtualization


Tagged as: apache dev devserver django guest host parallels server virtualization

Leave a Comment

Django Custom 404 for special cases

Django makes it easy to handle the output of 404 pages for the website, just define 404handler in urls and thats it.
But what happens if you need to show a different template for some specific method? Simple, create your own custom exception instead of using Http404.

Assuming we need this done for profile pages, when accessing some url that is restricted, let's define a ProfileHttp404 exception:

  1. #exceptions.py
  2. class ProfileHttp404(Exception):
  3. pass

To use it, let's assume that this should happen when accessing the profile page of a user that does not exists:
  1. #views.py
  2. from exceptions import ProfileHttp404()

  3. def profile(request, username):
  4. try:
  5. user = User.objects.get(username=username)
  6. except:
  7. raise ProfileHttp404()
  8. # profile page code

Accessing the profile page now, it will not return a 404 HTTP code, but a 500 one. Obvious, since we are raising an Exception. There is one more missing piece in the puzzle, something to catch this exception and render our specific template.

Middleware to the rescue!
  1. #middleware.py
  2. from exceptions import ProfileHttp404
  3. from django.views.defaults import page_not_found
  4. from django.http import HttpResponseNotFound

  5. class ProfileHttp404Middleware(object):
  6. """
  7. Make sure profile related 404 pages renders our specific template
  8. """
  9. def process_exception(self, request, exception):
  10. if isinstance(exception, ProfileHttp404):
  11. return HttpResponseNotFound(page_not_found(request, template_name='profiles/errors/404.html'))
  12. return None

Don't forget to add the middleware in settings.py in MIDDLEWARE_CLASSES.

Now we have a generic 404 template for all the site and a profile specific 404 template rendered each time ProfileHttp404 is raised.


Category: Django


Tagged as: 404 custom django

Leave a Comment

MacOS vim control+arrow functionality

Note: before doing any of this changes, make sure you back up your expse&spaces settings, terminal keyboard settings and .vimrc.

Being a fan of vim but unliking "gt" and "gT" to switch tabs and being used to do this by Control+arrows, raised a problem on MacOS.
The Linux .vimrc had simple commands:

  1. map <C-Up> :tabnew<CR>
  2. map <C-Down> :q<CR>
  3. map <C-Left> gT
  4. map <C-Right> gt

Obviously this commands didn't worked, first reason because it is used for Expose&Spaces.
So first step, change this shortcuts:
System Preferences > Expose and Spaces > Spaces

Changing it to Control+Option+arrow is good enough.

But this still doesn't fix the problem, because the Control+arrow doesn't reaches to vim. To see how vim interprets a combination of keys, you can press Ctrl+v followed by that combination. The result of this is just the arrow key, like control isn't even pressed.

Luckily mac term allows us to change keyboard settings and we can set it act on control+arrow as we want.
In order to find the correct marking for the action, looking at Xterm Control Sequences sending control means "Esc ["; as for the arrow keys, up=A, down=B, right=C and left=D.
So the keyboard settings will look something like this:


But it still doesnt work.
That's because vim receives this serie of characters: Esc[A
This is where vimrc helps us. Instead of mapping <C-Up> we map <Esc>[A resulting in:
  1. map <Esc>[A :tabnew<CR>
  2. map <Esc>[B :q<CR>
  3. map <Esc>[D gT
  4. map <Esc>[C gt

Enjoy your vim with control+arrows.


Categories: MacVim OS X vim


Tagged as: arrow control control arrow macos osx vim

4 Comments

Django Template Tag vs Kay Framework Processors

In our previous post we discovered how to obtain in Kay templates the same behavior as Django's inclusion tag. Another question pops in. What about template tags?

What is a template tag?

"A template tag is code that displays information dynamically in the template."

In other words, it's a method that handles the data based on the context and outputs it in the desired manner. The Django docs example is pretty clear:

  1. <p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>

  2. #output
  3. The time is 2010-09-03 11:13 PM

Kay framework doesn't allow you do import .py files to use their functions inside a template, because it's not transforming it in a list of nodes, like Django does.

CONTEXT_PROCESSORS

"Much like Django’s context processors Kay allows you to define a
number of functions that are run when templates are rendered that
make commonly used data available to your template
."

This is exactly what we have been searching for. Let's see how to define such a context processor and how to use it in a template for the Django example:

  1. # my_app.utils - defining the method
  2. import datetime
  3. def current_time(format_string = "%Y-%m-%d %I:%M %p")
  4. return datetim.datetime.now().strftime(format_string)

  5. # my_app.context_processors - create the processor
  6. from utils import current_time
  7. def current_time_processor(request):
  8. return {'current_time': current_time}

  9. # settings - include the processor
  10. CONTEXT_PROCESSORS = (
  11. ...
  12. 'my_app.context_processors.current_time_processor'
  13. )

  14. # template usage
  15. <p>The time is {{ current_time("%Y-%m-%d %I:%M %p") }}.</p>

  16. # output
  17. The time is 2010-09-03 11:13 PM

Applying processors for single view, not for the whole project

If the processor will only be used in a few templates, you can skip the part where we include it in the settings.CONTEXT_PROCESSORS tuple and send it when rendering the view's response:

  1. # my_app.views
  2. from kay.utils import render_to_response
  3. from context_processors import current_time_processor

  4. def current_time(request):
  5. return render_to_response('my_app/current_time.html', {}, processors=(current_time_processor,))

The only functionality that is missing is setting a variable in the context and there doesn't seem to be a solution for it.

Note: The returned value of your function will need the |safe filter applied to it to avoid HTML escaping.


Categories: GAE Kay Framework


Tagged as: context_processor django kay framework template tag

Leave a Comment

Django inclusion tag for Kay framework

Django inclusion tag helps you when you need to repeat the same HTML block for several times or keeping your design consistent site-wide.

How can you do the same in Kay framework? Is there such an option?

Well, first of all, you need to search in the right place, like the docs say:
Kay uses Jinja2 for rendering HTML templates.
So let's check the Jinja2 Template Designer Documentation. This is where the solution can be found: Macros

Macros

Macros are comparable with functions in regular programming languages. They are useful to put often used idioms into reusable functions to not repeat yourself.
This is exactly what we were searching for.

Lets take the polls results example from Django docs and transform it in a Kay/Jinja2 macro:

Django

  1. # polls.templatetags.poll_tags
  2. from django import template
  3. register = template.Library()

  4. @register.inclusion_tag('results.html')
  5. def show_results(poll):
  6. choices = poll.choice_set.all()
  7. return {'choices': choices}

  8. # templates/polls/results.html
  9. <ul>
  10. {% for choice in choices %}
  11. <li> {{ choice }} </li>
  12. {% endfor %}
  13. </ul>

  14. # templates/polls/view_poll.html
  15. {% load poll_tags %}
  16. {% show_results poll %}

Kay framework

  1. # templates/polls/macros.html
  2. {% macro show_results(poll) %}
  3. <ul>
  4. {% for choice in poll.choices_set.fetch(1000) %}
  5. <li> {{ choice }} </li>
  6. {% endfor %}
  7. </ul>
  8. {% endmacro %}

  9. # templates/polls/view_poll.html
  10. {% from "polls/macros.html" import show_results %}
  11. {{ show_results(poll) }}

First obvious difference, in Kay, the code doesn't stay in a separate .py file, but in an .html one which needs to be imported directly in the template where it is being used.

Unfortunately, if you need to handle the arguments in some special way, you are limited by normal template syntax only and this might not be the right solution.

Special macro + call

Jinja also comes with something extra by using macro + call together.  This is like calling a macro inside another macro and it is
useful as replacement for loops. 

  1. {% macro dump_users(users) %}
  2. <ul>
  3. {% for user in users %}
  4. <li><p>{{ user.username|e }}</p>{{ caller(user) }}</li>
  5. {% endfor %}
  6. </ul>
  7. {% endmacro %}

  8. {% call(user) dump_users(list_of_user) %}
  9. <dl>
  10. <dl>Realname</dl>
  11. <dd>{{ user.realname|e }}</dd>
  12. <dl>Description</dl>
  13. <dd>{{ user.description }}</dd>
  14. </dl>
  15. {% endcall %}


Categories: GAE Kay Framework


Tagged as: django inclusion tag kay framework macro

Leave a Comment

Calling instance methods with arguments inside Django templates

What to do in those strange situations where you need to use an instance's method, which needs at least one argument, in the template? You can't always generate the values from the views.py and send them in variables, imagine a for loop where you need to get it.

The easy way to do it is using Django filters.

Three solutions. Pick the one that fits your needs.

There are three solution presented in this article:
1. calling one method only which requires one argument;
2. calling one method only which requires more string/int arguments;
3. calling any method which requires one or more arguments.

The no argument case is a simple {{ instance.method }} call, so there is no point discussing it.

To illustrate our examples, we'll use the following model and call the template_call() method:

  1. from django.db import models

  2. class SomeObject(models.Model):
  3. some_field = models.TextField()

  4. def template_call(self, *args):
  5. """ this is the method that will be called """
  6. return ", ".join(args)

Calling one method only which requires one argument

The simplest case. We only need to call one method which requires only one argument. A normal filter is enough since we can hardcode the method's name in it and send the attribute as a parameter:

  1. #template_filters.py
  2. from django import template
  3. register = template.Library()

  4. @register.filter
  5. def test_simple_template_call(instance, args):
  6. """
  7. allows only one argument for one exact method
  8. """
  9. return instance.test_template_call(args)

  10. # template usage
  11. {{ instance|test_simple_template_call:"value1" }}

  12. # output
  13. value1

Calling one method only which requires more string/int arguments

This approach is similar to the one before, the difference is that the arguments will be passed as key=value pairs separated by '&'. To resolve them, we will use the same class Django uses to parse query strings out of URL's, since it is the same structure.

  1. #template_filters.py

  2. from django.http import QueryDict
  3. @register.filter
  4. def test_advanced_template_call(instance, args):
  5. """
  6. allows more arguments like a query dict:
  7. var_name=value&var_name2=value
  8. """
  9. qd = QueryDict(args)
  10. return instance.test_template_call(*qd.values())

  11. # template usage
  12. {{ instance|test_advanced_template_call:"var_1=value1&var_2=value2" }}

  13. # output (note the values order)
  14. value2, value1

Calling any method which requires one or more arguments

This is the complex one. You can send any number of arguments and specify which method to call. For this to happen we need not one, but two filters: one to set the arguments in the instance's attributes and one to name the method. The order the filters are called is essential: first the arguments and then the method.

  1. #template_filters.py

  2. @register.filter
  3. def template_args(instance, arg):
  4. """
  5. stores the arguments in a separate instance attribute
  6. """
  7. if not hasattr(instance, "_TemplateArgs"):
  8. setattr(instance, "_TemplateArgs", [])
  9. instance._TemplateArgs.append(arg)
  10. return instance

  11. @register.filter
  12. def template_method(instance, method):
  13. """
  14. retrieves the arguments if any and calls the method
  15. """
  16. method = getattr(instance, method)
  17. if hasattr(instance, "_TemplateArgs"):
  18. to_return = method(*instance._TemplateArgs)
  19. delattr(instance, '_TemplateArgs')
  20. return to_return
  21. return method()

  22. # template usage
  23. {{ instance|template_args:"value1"|template_args:"value2"|template_args:"value3"|template_method:"test_template_call" }}

  24. # output
  25. value1, value2, value3

With all this filters, you can choose the one that best fits your needs without over doing it.


Category: Django


Tagged as: django template tag

1 Comment

Resubmit form with errors and FileField or ImageField

urlize HTML safe

The form validation process is very useful and does not require too much code to be written. But what if you need to save certain fields when the form is not valid?

Let's consider the following models.py, forms.py and situation:

  1. # models.py
  2. from django.db import models

  3. class Avatar(modesl.Model):
  4. original_image = models.ImageField()

  5. class Character(models.Model):
  6. name = models.TextField()
  7. avatar = models.ForeignKey(Avatar, blank=True, null=True)


  1. # forms.py
  2. from django import forms
  3. from models import Character

  4. class CharacterForm(forms.ModelForm):
  5. name = forms.CharField(required=True, min_length = 3)
  6. avatar = forms.ImageField(required=True)

  7. class Meta:
  8. model = Character
  9. fields = ['name', 'avatar']

  10. def clean_avatar(self):
  11. """
  12. we need to return a Avatar object to match the model field type
  13. """
  14. img = self.cleaned_data.get('avatar')
  15. if not img:
  16. raise forms.ValidationError('You must select a character image')
  17. avatar = Avatar(original_image = img)
  18. avatar.save()
  19. return avatar

What will happen to the avatar field if the user inputs a name that is already in use? Its value will get deleted and you risk the user not noticing it, generating another form error page.

What can we do about it?

We don't have access to the session inside the clean method to set avatar.id in it, nor to form.cleaned_data in views.py.

We must use what we can: altering the data used to populate form fields values inside the avatar clean method. So let's add a separate hidden field that will store our avatar.id and we can now make the avatar as not required since it can be empty.

  1. # forms.py
  2. class CharacterForm(forms.ModelForm):
  3. name = forms.CharField(required=True, min_length = 3)
  4. avatar_id = forms.CharField(required=False, widget=forms.HiddenInput)
  5. avatar = forms.ImageField(required=False)

Very important: the order of the Meta fields. We want the avatar_id to be in front of avatar:

  1. # forms.py
  2. class Meta:
  3. model = Character
  4. fields = ['name', 'avatar_id', 'avatar']

This way the avatar_id field is evaluated before we modify its value and we don't risk getting our custom value getting overwritten with POST data.

The avatar_id value is set in the clean_avatar method, because that will still be the only place where we create the avatar.

  1. # forms.py
  2. def clean_avatar(self):
  3. img = self.cleaned_data.get('avatar')
  4. avatar_id = self.cleaned_data.get('avatar_id')
  5. # avatar or avatar_id must exist
  6. if not (img or avatar_id):
  7. raise forms.ValidationError('You must select a character image')
  8. if not img and avatar_id:
  9. try:
  10. avatar = Avatar.objects.get(id=avatar_id)
  11. return avatar
  12. except:
  13. raise forms.ValidationError('You must select a character image')

  14. avatar = Avatar(original_image = img)
  15. avatar.save()

  16. if not self.is_valid() and avatar:
  17. self.data['avatar_id'] = avatar.id

  18. return avata

Of course there are other ways, like adding a JavaScript to check all fields value before submitting the form, but this handles cases where the user disabled or the browser does not support JS.


Category: Django

Leave a Comment

Django urlize HTML safe

urlize HTML safe

The default django urlize filter is not HTML safe as the docs say.

Note that if urlize is applied to text that already contains HTML markup,
things won't work as expected. Apply this filter only to plain text.

The easy way to solve this problem is to use an HTML parser and make sure the filter is applied only to plain text.

BeautifulSoup functions

To get the HTML tags from a text, .findAll() is the way to go, but if we need the plain text, .contents is what we need. Given a simple example to see what is the difference:

  1. from BeautifulSoup import BeautifulSoup
  2. html = '<p>foo <a href="http://od-eon.com">http://od-eon.com</a> bar</p> foobar'
  3. soup = BeautifulSoup(html)
  4. soup.findAll()
  5. >>> [<p>foo <a href="http://od-eon.com">http://od-eon.com</a> bar</p>, <a href="http://od-eon.com">http://od-eon.com</a>]
  6. soup.contents
  7. >>> [<p>foo <a href="http://od-eon.com">http://od-eon.com</a> bar</p>, u' foobar']

The flow is clear to obtain a safe urlize from this simple example. We need to apply the urlize function on the .contents of each tag that the text contains:
Step 1. iterate over .contents and if its not a tag, do the replacement
Step 2. iterate over the tags, create a new BeautifulSoup instance from each tag
Step 3. if the new BeautifulSoup.findAll() returns more tags, for each of them repeat the process; if it doesn't, apply the urlize function and replace the tag in the main soup object

There is only one minor check that we should add in this case, what kind of tag are we converting now, because the http://od-eon.com inside the anchor tag it shouldn't convert to a new link, it already is one. So at Step 2. we need to check if tag.name is one of our accepted tags.

Here's how the code would look like:

  1. from django.template.defaultfilters import stringfilter
  2. from django.template import Library
  3. from django.utils.html import urlize
  4. register = Library()
  5. def html_urlize(value, autoescape=None):
  6. """Converts URLs in plain text into clickable links."""
  7. from BeautifulSoup import BeautifulSoup
  8. ignored_tags = ['a', 'code', 'pre']
  9. soup = BeautifulSoup(value)
  10. tags = soup.findAll(True)
  11. text_all = soup.contents
  12. for text in text_all:
  13. if text not in tags:
  14. parsed_text = urlize(text, nofollow=True, autoescape=autoescape)
  15. text.replaceWith(parsed_text)
  16. for tag in tags:
  17. if not tag.name in ignored_tags:
  18. soup_text = BeautifulSoup(str(tag))
  19. if len(soup_text.findAll()) > 1:
  20. for child_tag in tag.contents:
  21. child_tag.replaceWith(html_urlize(str(child_tag)))
  22. elif len(soup_text.findAll()) > 0:
  23. text_list = soup_text.findAll(text=True)
  24. for text in text_list:
  25. parsed_text = urlize(text, nofollow=True, autoescape=autoescape)
  26. text.replaceWith(parsed_text)
  27. try:
  28. tag.replaceWith(str(soup_text))
  29. except:
  30. pass
  31. return mark_safe(str(soup))
  32. html_urlize.is_safe = True
  33. html_urlize.needs_autoescape = True
  34. html_urlize = stringfilter(html_urlize)
  35. register.filter(html_urlize)


Category: Django

1 Comment

Django Admin - Order by ForeignKey field or method

Django Docs says that in Admin you can only display the __unicode__ representation of a ForeignKey field in list_display and it also allows you to define a custom function if you want to customize the display.

Let's take a simple Blog, Entry as example:

  1. # models.py
  2. class Blog(models.Model):
  3. name = models.CharField(_('Blog Name'), max_length=200)
  4. desc = models.TextField()

  5. class Entry(models.Model):
  6. blog = models.ForeignKey(Blog)
  7. title = models.CharField(max_length=200)
  8. post = models.TextField()

The target is to have the blog name in the Entry admin list view and also having it sortable.

Of course if will not work if you add it in list_display like 'blog__name'.

  1. # amin.py
  2. class EntryAdmin(admin.ModelAdmin):
  3. list_display = ('title',)

Half is done, you can now see it in admin.

Adding the Blog name in Entry admin

Easy way to do this is to define a function in the Entry model, allowing us to call it in the admin, just like any other field.

  1. # models.py
  2. class Blog(models.Model):
  3. name = models.CharField(_('Blog Name'), max_length=200)
  4. desc = models.TextField()

  5. class Entry(models.Model):
  6. blog = models.ForeignKey(Blog)
  7. title = models.CharField(max_length=200)
  8. post = models.TextField()

  9. def blog_name(self):
  10. return self.blog.name

Now we can add it in the admin:

  1. # amin.py
  2. class EntryAdmin(admin.ModelAdmin):
  3. list_display = ('title', 'blog_name')

Making it sortable by

Being a function in the model, it misses an attribute used by the admin admin_order_field to order.

  1. # models.py
  2. class Blog(models.Model):
  3. name = models.CharField(_('Blog Name'), max_length=200)
  4. desc = models.TextField()

  5. class Entry(models.Model):
  6. blog = models.ForeignKey(Blog)
  7. title = models.CharField(max_length=200)
  8. post = models.TextField()

  9. def blog_name(self):
  10. return self.blog.name
  11. blog_name.admin_order_field = 'blog__name'

Now you can actually order the results in entry admin list display by blog name.


Category: Django

6 Comments
Page generated in: 0.57s