Michal
Michal

Reputation: 71

Django - pass value from template to views function

I'm a Django beginner and I ran into an issue I'm not really sure how to solve. I'm building ecommerce website to practice. I have two main models: Product, Item. Where Product has value - memory, color, code, avalibility, etc. Item is a wrapper for multiple Products, so it's user's view of multiple products wrapped into one.

i.e.:

Products: Mobile-phone 128GB white; Mobile-phone 64GB black;...

Item : Mobile-phone (keeping both 128GB white and 64GB black "pointers")

So as my ItemDetailView(DetailView) I show to user an Item, can of course, show all possible colors and memory variants. But what I cannot figgure out is how to actually after user selects, for example via radio-buttons, in template.html page, color and memory send chosen variant to back-end (or views.py, if I undestand concept correctly).

My idea was to create model "ChosenProduct" carrying columns like "user", "color", "memory", "item". So after choosing both color and memory I could, ideally, create new object, holding all four parameters. With that I could show user it's availibility and after clicking "add to cart" btn adding it to the cart...

But the problem is, I don't know how to easily pass those parameters (color, size) that user chooses from template.html to actual function that handles this.

models.py

#presenting actual Product for sale
class Product(models.Model):
    code = models.CharField(max_length=30)
    colorCode = models.CharField(max_length=20, blank=True, null=True)
    rgb = models.CharField(max_length=20, blank=True, null=True)
    sizeCode = models.CharField(max_length=20, blank=True, null=True)
    avalibility = models.IntegerField(default=0)

    def __str__(self):
        return self.code


#wraps multiple Products
class Item(models.Model):
    title = models.CharField(max_length=100)
    description = models.CharField(max_length=10000)
    price_inclVat = models.FloatField()
    price_noVat = models.FloatField()
    price_discount_inclVat = models.FloatField(blank=True, null=True)
    price_discount_notVat = models.FloatField(blank=True, null=True)
    products = models.ManyToManyField(Product)
    slug = models.SlugField()
    label = models.CharField(choices=LABEL_CHOICES,
                             max_length=1, null=True, blank=True)


#my idea of presenting chosen variants in user's relation
class ChosenProduct(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE)
    color = models.CharField(max_length=20, blank=True)
    size = models.CharField(max_length=20, blank=True)
    item = models.ForeignKey(Item, on_delete=models.CASCADE)

    def __str__(self):
        return self.item.title

views.py (DetailView)

class ItemDetailView(DetailView):
    model = Item
    template_name = "product.html"

Could you please point me into correct direction and how to handle this operation using Django? I found multiple threads discussing request.GET but I don't want to pass parameters via URL (since that is from my understanding only option).

Thank you!

Upvotes: 1

Views: 228

Answers (2)

darkstar
darkstar

Reputation: 71

You are right to assume that you should not POST data using URL. I am assuming you understand django forms. If not please checkout this django form documentation. Now what you want is to render a form in your details template, this form will contain all your options & what not. The customer will submit the form with add to cart button or buy button. By submitting this form customer will send all chosen option to your django back-end.

#views.py
class ItemDetailView(SuccessMessageMixin, generic.DetailView):
    template_name = 'product.html'
    queryset = models.Item.objects.all()
    
   def get_context_data(self, **kwargs):
      context = super().get_context_data(**kwargs)
      context['title'] = "Details of Product: "
      context['item_form'] = forms.AddtoCart(instace=self.object)#* or use other ways to pass initial or default value to form
      return context

#forms.py
class AddToCart(forms.ModelForm):
   itemCode = forms.CharField(widget=forms.HiddenInput())
   itemoption = forms.BooleanField(label='Name', required=True, 
          widget=forms.CheckboxInput(
             attrs={
                     'placeholder': 'options are here '
                   }
            ))
 #etc


class Meta:
    model = Choosen_Item
    fields = ['itemCode', 'itemoption' ]
    # exclude = ['inputter', 'updater', 'updateOn']

#product.html
# skipped some code for brevity
<form action='url to where you want to process the submitted data'>
 {% csrf_token %}
 {{ item_form.as_p}}
 <button>Add to cart</button>
</form>

All this is assuming you are not using drf and also not using any kind of front end framework. !!I hope this helps!!

Upvotes: 1

Tokyo Developer
Tokyo Developer

Reputation: 97

this may help you . write this on your views and point a url to it

from django.shortcuts import render
def indexw(request):
    context_variable = ''
    context = {"context_variable": context_variable}
    return render(request,'index.html', context)

Upvotes: 0

Related Questions