Algumas dicas sobre o Django Forms

As dicas desse post foram tiradas da apresentação Advanced Django Forms Usage da DjangoCon, recomendo que todos vejam o vídeo e os slides.

Vídeo: [blip.tv http://blip.tv/play/AYLUlgsC width=”550″ height=”442″]

Slides: http://speakerdeck.com/u/maraujop/p/advanced-django-forms-usage

Esse primeiro exemplo mostra o uso tradicional de um form dentro de uma view do Django:

def my_view(request, template_name='myapp/my_form.html'):

    if request.method == 'POST':
        form = MyForm(request.POST) # Form #1!
        if form.is_valid(): # nested if!
            do_x()
            return redirect('/')
    else:
        form = MyForm() # Form #2!
        
    return render(request, template_name, {'form': form})

O principal problema desse código é que você tem o form declarado duas vezes quando é possível declarar uma única vez. Podemos reescrever esse código dessa forma:

def my_view(request, template_name='myapp/my_form.html'):

    # sticks in a POST or renders empty form
    form = MyForm(request.POST or None)
    if form.is_valid():
        do_x()
        return redirect('home')
    return render(request, template_name, {'form': form})

Agora temos menos linhas de código, o form declarado uma única vez e um if a menos.

No caso de um form com upload de arquivos, podemos fazer assim:

def my_view(request, template_name='myapp/my_form.html'):

    form = MyForm(request.POST or None, request.FILES or None)
    if form.is_valid():
        do_x()
        return redirect('home')
    return render(request, template_name, {'form': form})

Em todo projeto Django é comum que se use bastante os modelforms, nesse caso o uso tradicional é dessa forma:

def my_model_edit(request, slug=slug, template_name='myapp/my_model_form.html'):

    # I wouldn't call the variable model, because it's an instance of a model, it's confusing
    mymodel = get_object_or_404(MyModel, slug=slug)
    if request.method == 'POST':
        form = MyForm(request, instance=mymodel)
        if form.is_valid():
            mymodel = form.save()
            mymodel.day_shown = datetime.datetime.now() # Do any extra model stuff here
            mymodel.save()
            return redirect('home')
    else:
        form = MyForm(instance=mymodel)
    return render(request, template_name, {'form': form, 'model': mymodel})

Aqui temos o mesmo problema do form simples, o form é declarado duas vezes, podemos reescrever dessa forma:

def my_model_edit(request, slug=slug, template_name='myapp/my_model_form.html'):

    mymodel = get_object_or_404(MyModel, slug=slug)
    
    form = MyModelForm(request.POST or None, instance=mymodel)
    
    if form.is_valid():
        mymodel = form.save()
        mymodel.edited_at_djangocon = True
        mymodel.save()
        return redirect('home')
    
    return render(request, template_name, {'form': form, 'mymodel': mymodel})

Novamente temos menos linhas de código, o form declarado uma única vez e apenas um if.

Para um modelform de adição o código ficaria o seguinte:

def my_model_add(request, template_name='myapp/my_model_form.html'):
    
    form = MyModelForm(request.POST or None)
    
    if form.is_valid():
        mymodel = form.save()
        mymodel.added_at_djangocon = True
        mymodel.save()
        return redirect('home')
    
    return render(request,template_name,{'form': form})

Além dessas dicas existem várias outras na apresentação, recomendo mais uma vez a todos que assistam e baixem os slides.

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s