Thomas166
Thomas166

Reputation: 23

Django - update database item if exists or insert if not exists

I want to update item quantity in a database or add to inventory if the UPC doesn't already exist. I am not sure how to write the logic. Here's what I have so far:

My view:

from django.contrib.auth.decorators import login_required
from .forms import AuditItemForm
from .models import AuditItem
import datetime

@login_required
def audit_inventory(request):
    form = AuditItemForm(request.POST or None)
    if form.is_valid():
        form.save(commit=False)
        form_upc = form.cleaned_data.get('upc')
        qty = form.cleaned_data.get('qty')
        for instance in AuditItem.objects.all():
            if instance.upc == form_upc:
                instance.qty += qty
                instance.user = str(request.user)
                instance.last_updated = datetime.datetime.now()
                instance.save()
            elif instance.upc != form_upc:
                form.save(commit=True)
        return redirect('/audit')
    context = {
        "form": form,
        "title": "Audit Inventory",
    }
    return render(request, "audit.html", context)

What's wrong with my logic? It updates an item correctly but it doesn't allow me to add a new item that doesn't already exist.

Upvotes: 0

Views: 2394

Answers (2)

AngelSepulveda
AngelSepulveda

Reputation: 19

What you need is update_or_create(defaults=None, ** kwargs)

Explanation: A convenience method for updating an object with the given kwargs, creating a new one if necessary. The defaults is a dictionary of (field, value) pairs used to update the object. The values in defaults can be callables.

Returns a tuple of (object, created), where object is the created or updated object and created is a boolean specifying whether a new object was created.

The update_or_create method tries to fetch an object from database based on the given kwargs. If a match is found, it updates the fields passed in the defaults dictionary. The example of this method is:

obj, created = Person.objects.update_or_create(
first_name='John', last_name='Lennon',
defaults={'first_name': 'Bob'},
)

For more information: https://docs.djangoproject.com/en/3.2/ref/models/querysets/#update-or-create

Upvotes: 2

bazzuk123
bazzuk123

Reputation: 191

Not sure if it is what you want but maybe try get_or_create() function it will return item and boolean value if it was created or pulled from database

form = AuditItemForm(request.POST or None)
if form.is_valid():
    form.save(commit=False)
    form_upc = form.cleaned_data.get('upc')
    qty = form.cleaned_data.get('qty')

    # get item or create new one if it doesn't exist
    item, created = AuditItem.objects.get_or_create(upc=form_upc)

    # if it already exist, update quantity
    if not created:
       item.qty += qty
       item.user = str(request.user)
       item.last_updated = datetime.datetime.now()
     
    # whether item was created or updated save it to database
    item.save()

Upvotes: 2

Related Questions