Reputation: 83
I have the following model :
models.py :
class Product(models.Model):
name = models.CharField(blank=False, max_length=255)
description = models.TextField()
class Ingredients(models.Model):
ingredients = models.ForeignKey(Product, related_name='ingredients', on_delete=models.CASCADE, null=True)
salt = models.IntegerField(default=0)
pepper = models.IntegerField(default=0)
views.py :
def productdetails(request, product_pk):
product = get_object_or_404(Product, pk=product_pk)
ingredients = get_object_or_404(Ingredients, ingredients_id=product_pk)
salt = ingredients.salt
pepper = ingredients.pepper
if request.method == 'POST':
form = IngredientsForm(request.POST)
newvalue = form.save(commit=False)
newvalue.user = request.user
newvalue.save()
return render(request, 'xxx.html', {'product': product, 'form': IngredientsForm, 'salt': salt, 'pepper': pepper})
return render(request, 'xxx.html', {'product': product, 'iform': IngredientsForm, 'salt': salt, 'pepper': pepper})
def updateproduct(request, product_pk):
ingredients = get_object_or_404(Ingredients, ingredients_id=product_pk)
form = IngredientsForm(request.POST or None, instance = ingredients)
salt = ingredients.salt
pepper = ingredients.pepper
if form.is_valid():
form.save()
products = Product.objects.filter()
return render(request, 'xxx.html', {'products': products})
return render(request, 'xxx.html', {'form': form, 'salt': salt, 'pepper': pepper, 'product_pk': product_pk})
def createingredients(request, product_pk):
if request.method == 'POST':
ingredients = get_object_or_404(Ingredients, ingredients_id=product_pk)
form = IngredientsForm(request.POST or None, instance=ingredients
salt = ingredients.salt
pepper = ingredients.pepper
# here should be the code
return render(request, 'xxx.html', {'ingredients': ingredients, 'product_pk': product_pk})
In template:
<div class="container">
<strong>Ingredients:</strong>
<b>Salt: </b>{{ salt }} g <br>
<b>Pepper: </b>{{ pepper }} g <br>
<br>
Update ingredients:
{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endif %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update">
</form>
<br>
Add ingredient:
<form action="{% url 'createingredients' product_pk %}" method="POST">
{% csrf_token %}
<br />
<p>Name: <input type="text" name="ingredientname" /> Value: <input type="number" name="ingredientvalue" /> <input type="submit" value="Add"></p>
<br />
</form>
What I try to achieve is that in the template the user should be able to add, delete, update and view Ingredients as he wish. For example, user can add the sugar ingredient of that product ( which is not defined in the ingredients models ) with the value of 150 and after that to delete the salt ingredient. In this case the template will need to list only sugar and pepper ( as salt was deleted by user ) ingredients of that product and allow user to always change values or add/delete more ingredients of that product from the product detail page. The user should be allowed to add as many ingredients as he wants, no matter if those ingredients are not in the ingredients models. Appreciate any help.
Upvotes: 0
Views: 457
Reputation: 1435
What you want requires adding new columns in the ingredients table. Theoretically you can achieve that, with some scripting and custom management commands and cron jobs, but it will require you to build an entire sub-system that does it. Additionally allowing the user direct access to the database structure is not a practice you should consider in production ever. What you need is to alter your database design-replace the definition of the ingredients record with a type/name, value, unit triplet, and instead of adding column add records.
class Ingredients(models.Model):
class TYPE:
SALT = 0
PEPPER = 1
#add more here
class UNIT:
GRAM = 0
KILOGRAM = 1
LITER = 2
POUND = 3
#add more here
# an optional unit conversion
# call using Ingredients.UNIT.convert(unit1,unit2,quantity)
@staticmethod
def convert(from, to, quantity):
factor = 1
#calculate conversion factor here
....
return quantity * factor
ingredients = models.ForeignKey(Product, related_name = 'ingredients',
on_delete = models.CASCADE, null=True)
#an Ingredients.TYPE member. For example Ingredients.TYPE.SALT
type = models.IntegerField(default=0)
#an Ingredients.UNIT memeber. For example Ingrediens.UNIT.GRAM
unit = models.IntegerField(default=0)
quantity = models.IntegerField(default=0)
Upvotes: 1