1
resposta

Django - Como registro um dado de forma que se não existir crie um e se ja existir atualizar

Tenho um conjunto de livros alocados em prateleiras/estantes. Primeiro escaneio a prateleira e em seguida os livros nela ( pra localização). Os livros podem ser mudados de posição e diariamente são escaneadas as prateleiras novamente pra atualizar a localização. Mais os livros movidos estão gerando duplicidade ( registrado em duas posições, portanto nao posso localizar o correto)

Na lógica ao registrar um livro com mesmo código deveria apagar ou sobrepor o anterior com a nova posição. Tentei fazer utilizando update_or_create mas não consegui.

Grato !

model.py

class Shelf(models.Model):
    shelf = models.CharField(max_length=50, verbose_name="Shelf", null=True, blank=True)
    def __str__(self):
        return  ("{}".format(self.shelf))

class OrderNumberShelf(models.Model):
    roll_number_shelf = models.CharField(max_length=50, verbose_name="Roll Number", null=True, blank=True)
    shelf = models.ForeignKey(Shelf, on_delete=models.CASCADE,  null=True, blank=True)
    def __str__(self):
        return  ("{} ".format(self.roll_number_shelf))

views.py

def ShelfCreate(request):
    shelf = Shelf() 
    ShelfFormset = inlineformset_factory(
        Shelf, OrderNumberShelf, 
        form = MaterialShelfForms, 
        extra=0, 
        can_delete=False, 
        validate_min=True)

    if request.method == 'POST':
           forms_shelf = ShelfForm(request.POST, request.FILES, instance=shelf, prefix='main')
           formset_shelf = ShelfFormset(request.POST, request.FILES, instance=shelf, prefix='product')

           if forms_shelf.is_valid() and formset_shelf.is_valid():
               forms_shelf = forms_shelf.save(commit=False)
               forms_shelf.save()
               formset_shelf.save()
               return HttpResponseRedirect('loc')
    else:
        forms_shelf = ShelfForm(instance=shelf, prefix='main')
        formset_shelf = ShelfFormset(instance=shelf, prefix='product')

    context = {
        'forms_shelf': forms_shelf,
        'formset_shelf': formset_shelf,
    }
    return render(request, 'cadastros/location.html', context)

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

1 resposta

Olá Humberto, tudo bem com você?

Peço desculpas pela demora no retorno.

Para evitar a duplicação de livros, você precisa verificar se o livro já existe na prateleira antes de adicioná-lo novamente. Para fazer isso, você pode adicionar um método personalizado ao seu modelo OrderNumberShelf para verificar se o livro já existe na prateleira. Aqui está um exemplo de como você pode fazer isso:

class OrderNumberShelf(models.Model):
    roll_number_shelf = models.CharField(max_length=50, verbose_name="Roll Number", null=True, blank=True)
    shelf = models.ForeignKey(Shelf, on_delete=models.CASCADE,  null=True, blank=True)

    def __str__(self):
        return  ("{} ".format(self.roll_number_shelf))

    def save(self, *args, **kwargs):
        # Verifica se o livro já existe
        existing_book = OrderNumberShelf.objects.filter(
            roll_number_shelf=self.roll_number_shelf, shelf=self.shelf
        ).first()

        # Se existir atualiza
        if existing_book:
            existing_book.roll_number_shelf = self.roll_number_shelf
            existing_book.save()
        else:
            super().save(*args, **kwargs)

Com isso, sempre que você tentar salvar um objeto OrderNumberShelf, o método save verificará se o livro já existe na prateleira e, se sim, atualizará sua posição. Caso contrário, ele salvará o novo objeto como de costume.

Note que o método personalizado save deve ser adicionado ao modelo OrderNumberShelf, e não ao formulário ou à view. Ele substituirá o método save padrão do modelo e será chamado sempre que você tentar salvar um objeto OrderNumberShelf.

Todavia, vale ressaltar que como é um assunto externo ao curso e que não tenho acesso ao cenário completo do projeto incluindo a estrutura inicial do seu banco de dados, outros testes terão de ser feitos afim de obter o resultado esperado, mas espero que esta resposta seja um bom ponto de partida para a resolução do seu problema.

Espero ter ajudado. Continue mergulhando em conhecimento!

Abraços e bons estudos.

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!