Cómo correr Django (y Python) usando Apache y FastCGI

Resumo en este post como hacer funcionar Django en un servidor Linux con CentOS 4.4 usando Apache 2 y FastCGI. Estas cosas están dispersas en Internet, la principal finalidad del post es tenerlas juntas en algún sitio.

Por qué FastCGI y no mod_python

Es la primera pregunta que uno se hace: si mod_python funciona, para qué quieres usar FastCGI. No es porque fastcgi vuelve a estar de moda, por supuesto. El problema real es que mod_python y mod_php no se llevan bien, y de hecho en CentOS 4.4, usando mod_php, MySQL y mod_python, este último no funciona. Aquí y aquí (If you get a segmentation fault) se explican las posibles causas. Al parecer tiene que ver con el hecho de Apache usa la librería expat del sistema (y la precarga cuando se inicia el servidor de web), mientras que mod_python usa la versión de expat que fue compilada en la distribución de Python que tenga el sistema operativo. Si las dos versiones no coinciden, se produce un segmentation fault. También puede deberse a un cruce similar entre las librerías de MySQL, mod_php y mod_python, pero el resultado final es similar. En los dos casos Apache sigue corriendo y mod_python se reinicia, pero nuestro programa en Python no se ejecuta. El segfault queda registrado en el log de errores de Apache (/var/log/httpd/error_log o algún lugar cercano, dependiendo de esté instalado Apache) y el navegador queda en blanco.
Y por eso la necesidad de usar fastcgi para correr Django. [Read the rest of this entry...]


Leave a Comment

Django and Custom CheckboxSelectMultipleField

Note: as of Django version 0.95, this solution no longer works. But thanks to the newforms module, it is no longer necessary. Explanation of how it works can be found in this post

The problem: I have been using Django in a project for some weeks. The application needs to display a series of checkboxes on the webpage, but the HTML rendering of the formfields.CheckboxSelectMultipleField class does not offer the precise placement of each checkbox that is needed on the webpage. formfields.CheckboxSelectMultipleField is a descendant of SelectMultipleField and does not provide the ability to iterate through each of the possible choices, as formfields.RadioSelectField derived objects do:

<!-- choices is an formfields.RadioSelectField object 
      This is not possible with formfields.CheckboxSelectMultipleField derived objects.
-->
<div class="form-row">
<table><tr>
     {% for i in form.choices.field_list %}
           <td>;{{ i.field }}</td><td>{{i.name}}</td>
     {% endfor %}
     </tr>
</table>
</div>

The Solution: a custom CheckboxesMultipleSelectField based on the code from formfields.RadioSelectField.

CustomCheckboxSelectMultipleField is intended to be used in a custom Manipulator.

The code for the custom CheckboxSelectMultiple

from django.core import formfields</p>

<p>class CustomCheckboxSelectMultipleField(formfields.FormField):
    def <strong>init</strong>(self, field_name, choices=[], ul_class='', is_required=False, validator_list=[], member_name=None):
        self.field_name = field_name
        # choices is a list of (value, human-readable key) tuples because order matters
        self.choices, self.is_required = choices, is_required
        self.validator_list = [self.isValidChoice] + validator_list
        self.ul_class = ul_class
        if member_name != None:
            self.member_name = member_name</p>

<pre><code>def render(self, data):
    &amp;quot;&amp;quot;&amp;quot;
    Returns a special object that is iterable *and*
    has a default str() rendered output.

    This allows for flexible use in templates. You can just use the default
    rendering:

        {{ field_name }}

    ...which will output the radio buttons in an unordered list.
    Or, you can manually traverse each radio option for special layout:

        {% for option in field_name.field_list %}
            {{ option.field }} {{ option.label }}&amp;lt;br /&amp;gt;
        {% endfor %}
    &amp;quot;&amp;quot;&amp;quot;

    class CustomCheckBoxSelectMultipleRenderer:
        def __init__(self, datalist, ul_class):
            self.datalist, self.ul_class = datalist, ul_class
        def __str__(self):
            &amp;quot;Default str() output for this radio field -- a &amp;lt;ul&amp;gt;&amp;quot;
            output = ['&amp;lt;/ul&amp;gt;&amp;lt;ul %s&amp;gt;' % (self.ul_class and ' class=&amp;quot;%s&amp;quot;' % self.ul_class or '')]
            output.extend(['&amp;lt;li&amp;gt;%s %s&amp;lt;/li&amp;gt;' % (d['field'], d['label']) for d in self.datalist])
            output.append('&amp;lt;/ul&amp;gt;')
            return ''.join(output)
        def __iter__(self):
            for d in self.datalist:
                yield d
        def __len__(self):
            return len(self.datalist)

    datalist = []
    str_data_list = map(str, data) # normalize to string
    for i, (value, display_name) in enumerate(self.choices):
        checked_html = ''
        if str(value) in str_data_list:
            checked_html = 'checked=&amp;quot;checked&amp;quot;'
        datalist.append({
            'value': value, 'checked': checked_html,
            'name': display_name,
            'field': '&amp;lt;input type=&amp;quot;checkbox&amp;quot; id=&amp;quot;%s&amp;quot; name=&amp;quot;%s&amp;quot; value=&amp;quot;%s&amp;quot;%s/&amp;gt;' % \
                (self.get_id() + '_' + str(i), self.field_name, value, checked_html),
            'label': '&amp;lt;label for=&amp;quot;%s&amp;quot;&amp;gt;%s&amp;lt;/label&amp;gt;' % \
                (self.get_id() + '_' + str(i), display_name),
        })

    return CustomCheckBoxSelectMultipleRenderer(datalist, self.ul_class)

def isValidChoice(self, data, form):
    str_data = str(data)
    str_choices = [str(item[0]) for item in self.choices]
    if str_data not in str_choices:
        raise validators.ValidationError, _(&amp;quot;Select a valid choice; '%(data)s' is not in %(choices)s.&amp;quot;) % {'data':str_data, 'choices':str_choices}
</code></pre>

<p>


Leave a Comment