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)