fgalvao
fgalvao

Reputation: 460

Django - POST request not retrieved correctly

I'm working on a inventory control in Django and i want a form to control the action that will be made. If a record for the product already exist, it should update the quantity. If it doesn't exist, it should create the record for it. Besides that, one form field will have three choices. One will add the form value to que product quantity, other will subtract and another one will change to the value in the form.

The model is quite big, because i set some choices for the form fields. There it is:

from django.db import models
from django import forms
from django.forms import ModelForm

class Produto(models.Model):
    CAMISA = "CM"
    QUADRO = "QD"
    CANECA = 'CN'
    ESCOLHAS_PRODUTO = (
        (CAMISA, 'Camisa'),
        (QUADRO, 'Quadro'),
        (CANECA, 'Caneca'),
    )
    tipo = models.CharField(max_length = 40,
                            choices=ESCOLHAS_PRODUTO,
                            default=CAMISA)

class Camisa(Produto):    

    MASCULINA = 'MA'
    FEMININA_BASICA = 'FB'
    FEMININA_GOLA_V = 'FV'
    INFANTIL = 'IN'
    MODELO_CAMISA = (
        (MASCULINA, 'Masculina'),
        (FEMININA_BASICA, 'Feminina Basica'),
        (FEMININA_GOLA_V, 'Feminina Gola V'),
        (INFANTIL, 'Infantil'),
    )
    modelo = models.CharField(max_length = 50,
                              choices=MODELO_CAMISA,
                              )

    AMARELA = 'AM'
    AZUL_CLARO = 'AC'
    AZUL_ESCURO = 'AE'
    BRANCA = 'BR'
    CINZA = 'CI'
    LARANJA = 'LA'
    MARFIM = 'MA'
    ROSA = 'RO'
    PRETA = 'PR'
    VERDE_MUSGO = 'VM'
    VERMELHA = 'VR'
    CORES_CAMISA = (
        (AMARELA, 'Amarela'),
        (AZUL_CLARO, 'Azul Claro'),
        (AZUL_ESCURO, 'Azul Escuro'),
        (BRANCA, 'Branca'),
        (CINZA, 'Cinza'),
        (LARANJA, 'Laranja'),
        (MARFIM, 'Marfim'),
        (ROSA, 'Rosa'),
        (PRETA, 'Preta'),
        (VERDE_MUSGO, 'Verde Musgo'),
        (VERMELHA, 'Vermelha'),
    )
    cor = models.CharField(max_length = 40,
                                    choices=CORES_CAMISA,
                                    )

    TAMANHO_P = 'TP'
    TAMANHO_M = 'TM'
    TAMANHO_G = 'TG'
    TAMANHO_GG = 'GG'
    TAMANHO_XG = 'XG'
    TAMANHO_02_ANOS = '02'
    TAMANHO_04_ANOS = '04'
    TAMANHO_06_ANOS = '06'
    TAMANHO_08_ANOS = '08'
    TAMANHO_10_ANOS = '10'
    TAMANHO_12_ANOS = '12'
    TAMANHO_14_ANOS = '14'
    TAMANHO_CAMISA = (
        (TAMANHO_P, 'P'),
        (TAMANHO_M, 'M'),
        (TAMANHO_G, 'G'),
        (TAMANHO_GG, 'GG'),
        (TAMANHO_XG, 'XGG'),
        (TAMANHO_02_ANOS, '2 Anos'),
        (TAMANHO_04_ANOS, '4 Anos'),
        (TAMANHO_06_ANOS, '6 Anos'),
        (TAMANHO_08_ANOS, '8 Anos'),
        (TAMANHO_10_ANOS, '10 Anos'),
        (TAMANHO_12_ANOS, '12 Anos'),
        (TAMANHO_14_ANOS, '14 Anos'),
    )
    tamanho= models.CharField(max_length = 50,
                              choices=TAMANHO_CAMISA,
                              )




    quantidade = models.IntegerField()

    def __unicode__(self):
        return self.modelo


class CamisaForm(ModelForm):
    ADICIONAR = 'ADC'
    REDUZIR = 'RED'
    ALTERAR = 'ALT'    
    ACOES = (
        (ADICIONAR, 'Adicionar Quantidade'),
        (REDUZIR, 'Reduzir Quantidade'),
        (ALTERAR, 'Alterar para Quantidade'),        
    )
    acoes = forms.ChoiceField(
                              choices=ACOES,
                              )

    class Meta:
        model = Camisa

And the following view:

def index(request):
    produtos_estoque = Camisa.objects.all()
    template = 'estoque/index.html'
    modelos_camisa = {'MA' : 'Masculina Basica','FB' : 'Feminina Basica','FV' : 'Feminina Gola V','IN' : 'Infantil' }
    if request.method == 'POST':
        form = CamisaForm(request.POST)
        if form.is_valid():                
            try:
                produto_atualizar = Camisa.objects.get(modelo = request.POST['modelo'], cor = request.POST['cor'], tamanho = request.POST['tamanho'])            
                if request.POST['acoes'] == 'ADC':
                    produto_atualizar.quantidade = produto_atualizar.quantidade + request.POST['quantidade']
                elif request.POST['acoes'] == 'RED':
                    produto_atualizar.quantidade = produto_atualizar.quantidade - request.POST['quantidade']
                elif request.POST['acoes'] == 'ALT':
                    produto_atualizar.quantidade = request.POST['quantidade']
                produto_atualizar.save()
            except:
                produto_atualizar = form.save()
            return HttpResponseRedirect('')
    else:
        form = CamisaForm()
    return render_to_response(template, { 'form': form, 'produtos_estoque': produtos_estoque,
        'modelos_camisa' : modelos_camisa.iteritems(),  }, context_instance=RequestContext(request))

But what is happening is that the form is just creating another record for the product, even if it already exists. Not sure if the rest of the model is important for this question, will post it if necessary. Can somebody help me on this one? Thanks

Upvotes: 1

Views: 101

Answers (1)

markdsievers
markdsievers

Reputation: 7309

Please post the Model this is acting on - it will have some useful information, like constraints or lack thereof etc. OK cool, no unique constraints in there causing insert violations.

First thing I would recommend is using the forms cleaned_data to access form values instead of the raw POST data, form.is_valid() does a lot of work to process the raw data into acceptable inputs for Model data.

Second thing is that except clause will catch ANY exception which I suspect is your problem... Something else is going wrong which is creating the new record in the except clause. Be specific, like except Camisa.DoesNotExist:

Third thing is to put those constants on the Model so you can reference them from the Form and View instead of literal strings. This is just a cleanliness / code style recommendation.

A little cleanup might look like:

MODELOS_CAMISA = {'MA' : 'Masculina Basica','FB' : 'Feminina Basica','FV' : 'Feminina Gola V','IN' : 'Infantil' }

def index(request):
    produtos_estoque = Camisa.objects.all()

    if request.method == 'POST':
        form = CamisaForm(request.POST)
        if form.is_valid():
            try:
                produto_atualizar = Camisa.objects.get(modelo=form.cleaned_data.get('modelo'), cor=form.cleaned_data.get('cor'), tamanho=form.cleaned_data.get('tamanho'))
                quantidade = form.cleaned_data.get('quantidade')
                acoes = form.cleaned_data.get('acoes')
                if acoes == Camisa.ADC:
                    produto_atualizar.quantidade = produto_atualizar.quantidade + quantidade
                elif acoes == Camisa.RED:
                    produto_atualizar.quantidade = produto_atualizar.quantidade - quantidade
                elif acoes == Camisa.ALT:
                    produto_atualizar.quantidade = quantidade
                produto_atualizar.save()
            except Camisa.DoesNotExist:
                produto_atualizar = form.save()
            return HttpResponseRedirect('')
    else:
        form = CamisaForm()
    return render_to_response('estoque/index.html', { 'form': form, 'produtos_estoque': produtos_estoque,
        'modelos_camisa' : MODELOS_CAMISA.iteritems(),  }, context_instance=RequestContext(request))

(Sorry for any grammatical errors, my Portuguese is not great)

That should be enough to get you started, if you add more information I can edit and elaborate my answer. Good luck!

Upvotes: 1

Related Questions