» tagged pages
» logout
django
Return to django

Django Community Aggregator

(or Cancel)

(Editing anonymously: to be credited for your changes, login or register a new account)

other page actions:

Tags Applied to this Topic

1 person has tagged this page:

Aggregated feeds from the Django community.

Michael Trier: NewForms-Admin Lands in Django Trunk

Brian Rosner just now, with Changeset 7967, merged the NewForms-Admin branch of Django into Trunk. This is a huge step forward in the push to version 1.0. I want to personally thank all of the numerous contributors that have made NewForms-Admin possible. It’s been an enormous amount of work, and I am so appreciative. Thanks!

django: Django Community Aggregator

Greg Taylor: Browser Games with Django (English)

Just looking through DjangoSites.org and Googling around, I'm absolutely puzzled by the lack of Django-based browser games. It is such an idea platform for developing these, yet there are only a few that are actually open to the public (some of which aren't in English, and are thus inaccessible to me). There seem to be a few games out there in French, Chinese, and some other things I don't really recognize, though.

Here are a few games in English I've been able to round up:

I'm particularly interested in anything open-source, as I'd love to contribute from time to time, but I'd love to hear of any playable games that I have missed, or any open-source games in development. As far as close-sourced games in development, they're not of much interest to me if they're at least not open for testing. Without access to the source or a reachable site, it's as good as vaporware (and many of them never see completion).

So speak up, let me know if there's something that I've completely missed!

django: Django Community Aggregator

Armin Ronacher: Jinja2 Final aka Jinjavitus Released

The fiinal version of the Jinja2 Django-inspired template engine was just released. It comes with tons of improvements over the older Jinja1 engine and breaks backwards compatibility to some point over the old Jinja1 engine. It’s packaged as a separate package so that you can use both right next to each other for an easier [...]

django: Django Community Aggregator

Ryan Berg: Django back on Dreamhost?

An email from Dreamhost indicates official support for running Django. I'd like to learn a bit more before I trust their announcement.

django: Django Community Aggregator

Armin Ronacher: Deploying Python Web Applications

Every once in a while I’m really impressed by a library I stumble upon. A while back that was virtualenv, now i stumbled upon fabric. I was using capistrano for a project I was working on which was kinda okay but somehow I wasn’t sold to it. Yesterday however apollo13 stumbled upon fabric which is capistrano [...]

django: Django Community Aggregator

Cecil Meeks: BitCircle gaining steam, anonymous comments turned off and official cancelling of Django Beast.

My new search engine is gaining steam! Traffic has doubled in just two days. I hope the momentum keeps up!
http://bitcircle.com

Anyway, quite a few announcements in this post.

read more

django: Django Community Aggregator

Malcolm Tredinnick: Django People Around Washington DC?

(Regular readers, please pardon a small, targeted begging request.)

I'm trying to make it to Washington, DC, for the Django sprint on August 1. Is there anybody in the area who has a couch or floor I could sleep on for the night before the sprint and the night afterwards? If I can save having to buy a hotel room around the area in the peak of summer, that would be nice.

Any responses to "malcolm at pointy-stick" (or firstname.lastname at gmail). Thanks.

django: Django Community Aggregator

Michael Trier: This Week in Django 29 - 2008-07-13

This Week in Django is a weekly podcast about all things Django.

This week we have a special guest, Kevin Fricovsky, that joins us as we talk about DjangoCon, EuroPython, a few source commits, some cool projects from the community, and the Tip of the Week.

django: Django Community Aggregator

Ivan Sagalaev: Cicero: месяц спустя

Прошел месяц с переезда моих форумов на Cicero и мне захотелось поделиться тем, как оно все живет и работает. Благо, живет оно, если вкратце, хорошо, и делиться этим приятно :-) Месяц прошел в неспешном рефакторинге (наконец перевел формы на ModelForm, которых не сущетсвовало, когда начинал их писать), добавлении мелких удобств (автоподсветка URL’ов, чтение SRE из OpenID) [...]

django: Django Community Aggregator

Marinho Brandão: Load balancing e Cache com MySQL Proxy

Que tal aprender uma nova linguagem enquanto faz uma boa tarefa para melhorar a escalabilidade do banco de dados?

Bom, foi isso que eu fiz hoje durante quase todo o dia. Descobri no início do dia que Lua é a linguagem de script do MySQL Proxy e mergulhei pra fazer duas coisas bastante interessantes: Load Balancing e Cache de resultados.

Load Balancing

Eu conheço 3 formas de fazer load balancing com MySQL:

  • MySQL Cluster [1]
  • MySQL Proxy [2]
  • MySQL Master/Slave [3]

Mas na verdade não conhecia em profundidade nenhum deles, apenas uma idéia superficial.

No final de semana testei o Master/Slave. Parece ser o mais poderoso dentre os três métodos, mas usá-lo no Django significa mexer em boa parte do código do ORM. Não é a minha intenção. Cheguei a construir um backend pra isso, em cima do backend do MySQL, e até descobri que havia outro semelhante [4]. Mas nem o meu backend improvisado, nem o do Ivan Sagalaev me seduziram: muito limitado e cheio de falhas de design.

Pois bem, o MySQL Cluster também me desanimou depois que eu li diversos depoimentos contrários [5].

Sobrou o MySQL Proxy.

MySQL Proxy

Este é um software um tanto recente da MySQL, que basicamente faz a ponte entre o(s) servidor(es) de MySQL e a sua aplicação. É vantajoso pois é independente de linguagem ou framework: você desenha as regras e o que vem depois delas pouco importa, funciona da mesma forma.

http://marinho.webdoisonline.com/blog/p/diagrama_mysql_proxypng_172/?img=1

Não quero explicar como instala e usa este software, portanto vou me limitar ao script que montei para fazer load balancing. Não foi devidamente testado e em algumas situações foi exibido o erro (1105, '#07000(proxy) all backends are down'), portanto, antes de ir migrando seu servidor, faça muitos testes e verifique mais detalhes.

O script, feito em Lua, ficou assim

function connect_server()
    local num = tonumber(os.date("%S")) % 2
    proxy.connection.backend_ndx = num + 1
    print("Using " .. proxy.backends[proxy.connection.backend_ndx].address)
end

Salve o arquivo como load_balancing.lua e execute da seguinte forma:

mysql-proxy \
    --proxy-lua-script=load_balancing.lua \
    --proxy-backend-addresses=127.0.0.1:3306 \
    --proxy-backend-addresses=vs2:3306

O parâmetro --proxy-backend-addresses pode ser repetido quantas vezes quiser, um para cada réplica do MySQL, quanto mais réplicas, mais poderoso é o seu "cluster".

Os hosts "127.0.0.1" e "vs2" são respectivamente, minha máquina e uma máquina virtual rodando no vmware-server, portanto, use os IPs ou hostnames conforme a sua realidade.

Ele não suporta master/slave (não encontrei nada na documentação que orientasse como fazer nesse caso), portanto foi necessário configurar os hosts como master/master, que você pode ver como fazer em [6]

O funcionamento é assim: nos segundos pares as conexões são repassadas ao servidor 1, e nas ímpares as conexões são repassadas para o servidor 2. Se houvessem 10 servidores, o módulo de 2 (local num = tonumber(os.date("%S")) % 2) seria feito com 10 (local num = tonumber(os.date("%S")) % 10) e o comando de chamada do mysql-proxy teria 10 vezes o parâmetro --proxy-backend-addresses. Simples né?

Cache em memória

Bom, eu já havia feito o mesmo tipo de coisa hackeando a QuerySet e criando o método .cache() [7], que me ajudou muito. Esta solução que eu criei hoje pode ser considerado inferior à anterior por oferecer menos granularidade e funcionar somente com MySQL, mas caso você não queira modificar o código original do Django, esta pode ser uma boa alternativa para você.

Este segundo script funciona da seguinte forma: quando uma consulta do tipo SELECT é feita ao banco de dados, seu resultado é armazenado em um servidor Memcached, com tempo de expiração definido por pattern (cada pattern, ou seja, cada modelo de SELECT pode possuir um tempo de expiração diferente) e se uma cosulta idêntica for requisitada dentro do tempo de expiração, o servidor de cache será consultado, ao invés do banco de dados.

Bacana né?

Então lá vai

-- Packages required
require("Memcached") -- http://luamemcached.luaforge.net/
require("json")      -- http://www.chipmunkav.com/downloads/Json.lua

-- Connect to memcached server
local conn = Memcached.Connect('localhost', 11211)

-- Default expire time for cache items
local default_expire_time = 30

-- Prefix for cache keys
local key_prefix = 'mysql-proxy-'

-- Patterns to define expiration time for different types of queries.
-- More details in: http://lua-users.org/wiki/PatternsTutorial
local patterns_expire_time = {
    {'^%s*select .+from .*auth_user', 150},
    {'^%s*select', default_expire_time},
}

-- Converts a string to valid key
function encode_key(str)
    return key_prefix .. string.gsub(str, ' ', '-')
end

-- Converts a resultset to JSON. This can't be done by
-- Json library directly because it's a userdata datatype
-- instance
function resultset_to_str(resultset)
    local rfields = resultset.fields
    local rrows = resultset.rows

    local fields = {}
    local rows = {}
    local pos = 1

    -- Rows
    for row in rrows do
        rows[pos] = row
        pos = pos + 1
    end

    -- Fields
    pos = 1
    for i = 0, #rfields do
        if rfields[i] then
            fields[pos] = {
                type = rfields[i].type,
                name = rfields[i].name,
            }
        end

        pos = pos + 1
    end

    return Json.Encode({
        fields = fields,
        rows = rows,
    })
end

-- Callback called before request database server
function read_query(packet)
    if string.byte(packet) == proxy.COM_QUERY then
        local sql = string.sub(packet, 2)

        if string.match(string.lower(sql), '^%s*select') then
            -- Transform to valid key string
            local key = encode_key(sql)

            -- Gets from cache
            local rset = conn:get(key)

            -- If not found in cache, requests from database server
            if rset == nil then
                proxy.queries:append(1, packet)
                return proxy.PROXY_SEND_QUERY
            end

            -- Print out
            print('from cache', key)

            -- Json -> table
            rset = Json.Decode(rset)

            -- Todo: check for error returns
            proxy.response.type = proxy.MYSQLD_PACKET_OK
            proxy.response.resultset = rset

            return proxy.PROXY_SEND_RESULT
        end
    end
end

-- Callback called after request to database server
function read_query_result(inj)
    local res = resultset_to_str(inj.resultset)
    local sql = string.lower(string.sub(inj.query, 2))
    local key = encode_key(sql)
    local expire_time = default_expire_time

    -- Looks at patterns for respective expire time
    for i = 0, #patterns_expire_time do
        if patterns_expire_time[i] and string.match(sql, patterns_expire_time[i][1]) then
            expire_time = patterns_expire_time[i][2]
            break
        end
    end

    -- Saves to cache
    conn:set(key, res, expire_time)
end

Lá no início, as linhas que definem local conn e local patterns_expire_time devem ser ajustadas à sua realidade (endereço do servidor e patterns). Para saber como definir expressões regulares em Lua veja em [8] (é um pouquinho diferente do convencional).

Este script depende de dois pacotes externos à linguagem: json.lua [9] e Memcached.lua [10], que por sua vez depende do LuaSocket [11].

No Ubuntu, quando se instala o pacote mysql-proxy a lib da Lua 5.0 é instalada também, mas acontece que os pacotes que eu citei acima - especialmente o LuaSocket - não funcionam corretamente com a versão 5.0.

A solução foi instalar a versão 5.1 em paralelo (o LuaSocket possui um pacote no Ubuntu chamado liblua5.1-socket2) e eliminar a pasta antiga de bibliotecas da versão 5.0 (/usr/share/lua/50/), criando um symlink da versão 5.1 (/usr/share/lua/5.1/) com o mesmo nome.

Ainda foi necessário definir a seguinte variável de ambiente

export LUA_INIT=@/usr/share/lua/50/compat-5.1.lua

Por fim, para dar vida ao script, basta executar

mysql-proxy \
    --proxy-lua-script=cached_queries.lua \
    --proxy-backend-addresses=127.0.0.1:3306
http://marinho.webdoisonline.com/blog/p/tela_mysql_proxypng/?img=1

Ao executar este comando, será aberta a porta 4040 que deve ser setada na setting DATABASE_PORT. Caso queira saber como sobrepor a porta 3306, veja em [19].

Uma observação importante: o MySQL possui um bug [12] (ou sei lá o que é) que obriga conexões para "localhost" serem via porta 3306, isso vale tanto para o client quanto para o pacote MySQLdb do Python. Você faz uma conexão para a porta 1365465321 ou qualquer outra e ele aponta para 3306. Portanto, ao usar a porta 4040, mude a setting DATABASE_HOST para "127.0.0.1" caso esteja usando "localhost".

No script acima há ainda uma séria limitação quanto ao tamanho da SELECT. Caso ela tenha mais que 245 caracteres, você terá um erro de tamanho da chave no cache. A solução é converter a expressão SELECT com MD5, SHA ou outor algorítimo que crie uma string única em cima de uma SELECT complexa. Eu não consegui fazer isso ainda, mas recomendo expressamente que faça esse ajuste eu espere que eu o faça antes de colocar em um servidor de produção.

Para mais detalhes sobre MySQL Proxy, veja em [13], [14], [15] e [16]

Para mais detalhes sobre Lua, veja em [17] e [18].

É isso aí... artigo feito no fim da noite tem quer ser rápido assim. Dúvidas, é só falar :)

PS: apesar de serem muito úteis para quem usa Django, todas essas configurações são compatíveis com qualquer linguagem ou sistema operacional, e com versões igual ou acima de 5.1 do MySQL.

PS2: agradeço ao Javier Guerra e David Given pos esclarecimentos sobre a arquitetura da Lua e ao Giuseppe Maxia pelo bom tutorial [19] que desenvolvou sobre MySQL Proxy

PS3: essa foi a primeira vez na vida que escrevi algo em Lua, por favor, sinta-se à vontade para apontar eventuais falhas

Links relacionados

[1]http://dev.mysql.com/downloads/cluster/index.html
[2]http://forge.mysql.com/wiki/MySQL_Proxy
[3]http://dev.mysql.com/doc/refman/5.1/en/connector-j-reference-replication-connection.html
[4]http://softwaremaniacs.org/soft/mysql_cluster/en/
[5]http://blog.globoi.com/producao/2008/04/16/brasileiros-na-mysql-conference/
[6]http://www.howtoforge.org/mysql_master_master_replication
[7]http://marinho.webdoisonline.com/blog/p/metodo-cache-para-queryset_158/
[8]http://lua-users.org/wiki/PatternsTutorial
[9]http://www.chipmunkav.com/downloads/Json.lua
[10]http://luamemcached.luaforge.net/
[11]http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/
[12]https://bugs.launchpad.net/ubuntu/+source/mysql-dfsg-5.0/+bug/241802
[13]http://del.icio.us/marinho/mysql+escalabilidade
[14]http://dev.mysql.com/doc/refman/5.1/en/mysql-proxy.html
[15]http://dev.mysql.com/doc/refman/5.1/en/mysql-proxy-scripting.html
[16]http://classdump.org/articles/2008/02/14/mysql-proxy-enhancements
[17]http://www.lua.org/manual/5.1/pt/
[18]http://lua-users.org/wiki/TutorialDirectory
[19](1, 2) http://dev.mysql.com/tech-resources/articles/proxy-gettingstarted.html

django: Django Community Aggregator

Patrick Altman: GitHub Enables Markdown Documentation

I have been desiring to have the documentation that I write for my various projects on GitHub render to HTML when using a .markdown extension, just like they support doing for special files like README.markdown. At first, I thought they’d eventually get around to it and that is the best I could hope for as surely [...]

django: Django Community Aggregator

Alberto García Hierro: First wapi release

Wapi is somewhat 80% finished, so I think it's ready for the first release. The zipfile includes the wapi code as well as some examples taken from byNotes.

You'll notice there are authentication methods for Basic, Digest and OAuth. However, only the former is usable for now, since the other two depend on Django applications which are't ready for release (but are likely to be ready before this week ends).

If you try this, leave some feedback in a comment ;). I advise you to not use this code into production yet, since the API may change in the near future.

django: Django Community Aggregator

Michael Trier: DjangoCon Officially Announced

There’s been lots of discussion and hints over the past several days about a forthcoming Django based conference called DjangoCon. The official announcement was just released. I’ve always been fond of small intimate group settings and this one will certainly be that with only 200 attendees allowed to participate. I only hope that I get one of the coveted spots.

django: Django Community Aggregator

Eric Florenzano: First Two Django Screencasts

It's always been a goal of mine to post screencasts here on my blog, but for whatever reason I never ended up getting around to it. Today, that all changes as I have created two new screencasts. Of course, this space is already very well-covered by both Michael Trier and Brian Rosner, so hopefully this adds something new to the conversation.

Setting up a Django Development Environment

In this screencast I show how I typically set up my Django development environment. It goes through installing Django by checking out the latest development version and linking it to the correct places on your system. It also talks about how to install reusable applications. Finally, it covers how to update all of those projects and keep a toolbox of snippets for your personal use.

The simple pylink command that I use in the screencast is this:

#!/bin/bash
ln -s `pwd`/$1 `python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"`/$1

Please let me know in the comments if you have any other tips and tricks for setting up a development environment for Django.

Using Django-Pagination

Django-pagination is an application that I wrote and released a while ago, which I use all the time, but that hasn't really seen much attention. In this screencast, I show how to take an existing project with too much data on one page, and use django-pagination to quickly and easily paginate the items on the page. There is a bit more documentation for the project that's available in the project directory if you do a subversion checkout, and docstrings throughout the source code, if you're interested in how it works.

Keep in Mind

These are my very first screencasts, ever. I'm not entirely sure what I'm doing yet, and the only way I can improve is by your feedback. If you have any advice and/or criticisms of these screencasts, please don't keep your mouth shut--speak up, and let me know in the comments. Hopefully someone finds these useful, and thanks for watching!

django: Django Community Aggregator

Eric Holscher: DjangoCon September 5-6, at Google!

Heard from Robert Lofthouse on Twitter. The Djangocon 2008 conference will be held at Google Campus (Googleplex) in Mountain View!! September 6 and 7th. That's only two months away, so hopefully this gets pulled together well. An official post should be up on djangoproject.com soon, and the conference website will launch on Friday.

django: Django Community Aggregator

Simon Willison: A quote from Robert Lofthouse

DjangoCon 2008. Venue: Gooleplex, San Francisco Bay Area. Dates: 6th and 7th Sept. Official post will be on djangoproject.com soon.

- Robert Lofthouse

django: Django Community Aggregator

Ivan Sagalaev: Спринт финишировал

Ну что же, мы поспринтовали! С меня — короткий отчет. Из собиравшихся 30 человек пришли, если не ошибаюсь, 18. Учитывая всякие тенические накладки, начали спринт мы где-то через час после назначенного времени. WiFi был, электричество тоже :-). И тут я должен сказать, что думал, что этого будет достаточно. Но ошибся. Довольно скоро стало понятно, что схема, когда [...]

django: Django Community Aggregator

Marinho Brandão: Migrando do mod_python para o mod_wsgi

Já faz alguns meses que eu queria fazer alguns testes com o mod_wsgi, a alternativa ao mod_python que vem sendo cada vez mais comentada e sugerida na comunidade Django.

Ontem eu aproveitei o dia tranquilo pra unir o útil ao agradável e colocar isso em prática.

O que é WSGI?

Vamos "começar do começo": WSGI é mais simples do que parece, trata-se de uma interface definida pela PEP 333 [1] para intermediar a comunicação entre servidores web e frameworks Python. Ela surgiu pela necessidade qualquer um de nós nota com um pouco tempo: Python tem quilos de frameworksmuitas delas excelentes, e às vezes o mod_python parece ser um ornitorrinco em um ninho de coelhos quando implantamos alguns sites. É esquisito.

/blog/p/diagrama_apache_wsgi_djangopng/?img=1

Mudando para o mod_wsgi

Para usar o WSGI puramente, é bastante simples, vamos fazer um pequeno script para ilustrar

def application(environ, start_response):
    status_code = '200 OK'
    headers = [('Content-Type', 'text/html')]

    start_response(status_code, headers)

    return ['So <b>testando</b>!']

from paste import httpserver
httpserver.serve(application, port='8000')

Ao executar este script minúsculo e carregar em seu navegador a URL "http://localhost:8000", será exibido "So testando". Simples não? Veja

$ python my_app.py
serving on http://127.0.0.1:8000
/blog/p/teste_wsgigif/?img=1

No Django, a coisa exige só um pouco mais de detalhes, mas nada complexo. Como já explanado há poucos dias pelo Eric, da Metaphormedia, em [2], é recomendável que se crie dentro de seu projeto uma pasta "apache" com um script dentro chamado "django.wsgi" - estes nomes são escolha sua, mas eles têm sido usados por mais de uma referência. Com o conteúdo abaixo (modificado segundo as suas necessidades)

#!/usr/bin/env python
import os, sys

sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)+'/../'))

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

E configure seu apache, removendo o código que implementa o mod_python e adicionando o seguinte

WSGIScriptAlias / /caminho/do/seu/projeto/apache/django.wsgi

Agora, para funcionar, é preciso que seu sistema operacional tenha o mod_wsgi instalado. No Ubuntu/Debian você instala com o seguinte comando

$ sudo apt-get install libapache2-mod-wsgi

Pronto, ao reiniciar o Apache, seu projeto estará lá, bonitão, rodando através do WSGI :)

Porque mod_wsgi?

Bom, essa deve ser a pergunta que você deve estar se fazendo. Se o mod_python sempre foi a alternativa recomendada e funciona bem, porque mudar para o mod_wsgi?

O mod_wsgi tem se comportado mais escalável que o mod_python. Por escalabilidade, entende-se a capacidade de um site de suportar o crescimento de uso sem perder a performance ou travar.

Ao ajustar um servidor para usar o mod_wsgi, pude notar essas diferenças. Elas não são tão grandes que se possa perceber com um simples teste com Apache Bench. É necessário forçar para notar a diferença, que tem sido até 10% superior.

Esse servidor que usei para fazer esses testes é uma VM (em Xen) com 512MB de RAM, rodando em um amd64, numa rede bastante estável, em Londres, enquanto que o Apache Bench foi executado em minha máquina.

Veja abaixo como os dois modos se comportaram:

Para compreender a legenda, o número após o "n" trata-se da quantidade de requisições enviadas e o número após o "c" trata-se da quantidade de requisições concorrentes, ou seja, "n1000c5" equivale a "1000 requisições enviadas de 5 em 5).

Tempo de resposta por requisição

/blog/p/tempo_de_resposta_por_requisicaopng/?img=1

Requisições por segundo

/blog/p/requisicoes_por_segundopng/?img=1

Load de 1 minuto

/blog/p/load_de_1_minutopng/?img=1

Load de 5 minutos

/blog/p/load_de_5_minutospng/?img=1

RSS / Memória real ocupada

/blog/p/rss_memoria_ocupadapng/?img=1

Percentual da CPU

/blog/p/percentual_da_cpupng/?img=1

Conclusões

Todos os números apresentados acima não podem ser tomados como base exata para comparação, por alguns motivos, como a influência que o teste anterior efetua no subsequente, a oscilação da internet e a influência de outros processos.

Eu fiz questão de usar um servidor em produção onde está sendo servido um outro sistema da empresa, que mesmo que não estivesse em seu horário de pico, era usado normalmente por alguns usuários.

Há ainda toda a questão de controvérsias em torno do uso real da CPU e da memória.

Mas dá pra notar uma realidade clara: o mod_swgi se mostra mais vantajoso em memória e tempo de resposta. Não esqueçamos que 200 requisições concorrentes para um VPS com 512MB de RAM é uma senhora carga, equivalente a alguns milhões de pageviews por mês.

No teste de 2000 requisições a 200 concorrentes, ficou visível que a configuração de MaxRequestsPerChild (de 1000) entrou em cena e fez diferença no desempenho, tanto para segurar a carga quando para mudar um pouco a evolução do desempenho.

Por fim, devo avisar que no teste seguinte, de 5000 requisições a 200 concorrentes, o Apache caiu antes de completar 3000, em 3 tentativas.

Mais detalhes sobre o WSGI podem ser encontrados em [4], [5] e [6]

Links relacionados

[1]http://www.python.org/dev/peps/pep-0333/
[2]http://www.ericholscher.com/blog/2008/jul/8/setting-django-and-mod_wsgi/
[3]http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango
[4]http://www.slideshare.net/hdiogenes/wsgi-a-resposta-para-a-questo-definitiva-sobre-python-a-web-e-tudo-mais-368429?src=embed
[5]http://en.wikipedia.org/wiki/Wsgi
[6]http://www.wsgi.org/wsgi/
[7]http://del.icio.us/marinho/wsgi

django: Django Community Aggregator

Wolfram Kriesing: Installing MySQLdb on Leopard

Thanks to Arne we got it done pretty quickly.

django: Django Community Aggregator

Page 1 | Next >>
Username:
Password:
(or Cancel)