Short question : how can I pass the user's input from a form, to the parameter of my method class ?

The user type a number, and this number is used in the method to multiply another value from the Class fields.

I tried dozen of things, but cant figured out what I am doing wrong If I update the method to use a constant instead of a variable, everthing is rendering as I want on the template

I keep running into missing positional arguments error.

Model

class Product(models.Model):
    sku = models.CharField(max_length=30)
    price = models.DecimalField(max_digits=5, decimal_places=2)

    def __str__(self):
        return self.sku

    def multi(self, n = 2):      #setting up a default of 2 initiate
        np = self.price * n      #the method and show self.multi in template
        return np              

Views

def index(request):
    list = Product.objects.all()

    if request.method == "POST":
        form = Input(request.POST or None)

        if form.is_valid():
            value = request.POST.get('data')
            value = form.cleaned_data.get('data')
            x = Product.multi()           # code broken, it does not 
            x(value)                      # initialize the method

    else:
        form = Input(request.POST or None)

Form

class Input(forms.Form):
    data = forms.DecimalField()

template : something around


        {% for item in list %}
        <div>
     {{ item.sku }} {{ item.price }} {{ item.multi }} </div>
{% endfor %}

1 Answers

0
Omar On

I believe what you are trying to achieve can be done via template tags and filters. Since by default you can't send parameters into a method of a class instance via the Django template system you need to get creative with template tags. https://docs.djangoproject.com/en/2.2/howto/custom-template-tags/

I would do the below:

# tags.py
from django import template
register = template.Library()
@register.filter
def multi(product, multiple):
    return product.multi(multiple)

In your view

def index(request):
    list = Product.objects.all()
    value = 2  # some default you want
    form = Input(request.POST or None)
    if request.method == "POST":
        if form.is_valid():
            value = form.cleaned_data.get('data')
    return render(request, 'template.html', {'value': value, 'form': form, 'list': list})

In your template

{% load tags %}
{% for item in list %}
    <div>{{ item.sku }} {{ item.price }} {{ item|multi:value }} </div>
{% endfor %}

Where value is the value entered on the form which you can feed into the context of the template page rendered

Hope that helps