Home > Mobile >  Django: Setting IntegerField after form submit
Django: Setting IntegerField after form submit

Time:08-19

How do i increase the "availability" IntergerField after the form is submitted?

Each new product_type is created in the admin panel since i'll only ever need a few of them. Each new product is created through a form.

views.py

def new_product(request):
    if request.method != 'POST':
        # No data submitted, create blank form
        form = ProductForm()
    else:
        # POST data submitted, process the data
        form = ProductForm(data=request.POST)

    if form.is_valid():
        product = form.save(commit=False)
        product.owner = request.user
        #product.product_type.availability  = 1    # This didn't work
        #product.product_type.add_product()        # And this didn't work
        product.save()


        return redirect('store')
        
    context = {'form': form}
    return render(request, 'store/new_product.html', context)

models.py

class ProductType(models.Model):
    availability = models.IntegerField(default=0) ## How to increase this on the fly?
    price = models.DecimalField(max_digits=7, decimal_places=2, default=6.99)
    product_type = models.CharField(max_length=200, default="Tier1")
    cores = models.IntegerField(default=1)
    ram = models.IntegerField(default=2)
    disk = models.IntegerField(default=10)

    def __str__(self):
        return self.product_type

    def add_product(self):
        self.availability = self.availability   1
        print(self.availability)

forms.py

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['host_name', 'host_password', 'product_type']

CodePudding user response:

Given the solutions you use, you can override the save() method.

# models.py

def save(self, *args, **kwargs):
    self.availability  = 1
    super().save(*args, **kwargs)

CodePudding user response:

I would suggested you to use post_save signals provided by Django. Signals are an awesome way to approach these kind of problems. Where you wish to perform dependent actions.
When A happens perform B
When A happens and C is in some state perform B

You can create custom signals, and if you want you can use already existing Django Model save signals ( post_save, pre_save etc )


This is how you implement custom signals
import django.dispatch
product_save_signal = django.dispatch.Signal()

You can emit these signals from anywhere you want. Suppose you want to emit this on Product Model Form save. In your case this can go into your new_product function.

def save(self, *args, **kwargs): # signature of save for the class you are overriding
    super().save(*args, **kwargs)
    pizza_done.send(sender=<pass_your_sender_here>, <pass other data as kwargs here>)

How to use this signal

@receiver(product_save_signal)
def action_after_product_save(sender, task_id, **kwargs):
    product_type_instance = Product.objects.filter(<some_query>).first()
    product_type_instance.availability = F('availability')   1
    product_type_instance.save()

Note: You should always use F('availability') 1 i.e F queries to perform increments and similar operation to ensure Django handles race conditions.

CodePudding user response:

While i did learn something new while trying out the ideas in your answers, the solution was far simpler than i thought.

The answer to my proflem was to use F('availability') 1 and not availability = 1 and then updating ProductType from the Product model.

It looks like this:

models.py

class ProductType(models.Model):
    availability = models.IntegerField(default=0)
    price = models.DecimalField(max_digits=7, decimal_places=2, default=6.99)
    product_type = models.CharField(max_length=200, default="Tier1")
    cores = models.IntegerField(default=1)
    ram = models.IntegerField(default=2)
    disk = models.IntegerField(default=10)

    def __str__(self):
        return self.product_type

    def update(self, *args, **kwargs):
        self.availability = F('availability')   1
        super().save(*args, **kwargs)

    def check_availability(self):
        if self.availability > 0:
            return True
        else:
            return False


class Product(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    host_name = models.CharField(max_length=200, default="")
    host_password = models.CharField(max_length=200, default="")
    product_type = models.ForeignKey(ProductType, null=True, blank=True, on_delete=models.CASCADE)

    def __str__(self):
        return self.host_name

    def save(self, *args, **kwargs):
        self.product_type.update()
        super().save(*args, **kwargs)
  • Related