how can i save html checkbox value to django database - django

I'm working on a subscription project that allows user select multiple services using checkbox and then calculate the total price for these services(something like selecting multiple mails from your mail account), I have these in the HTML and Js code but I wan to be able to store each selected services to the DB, please how can I archive this
<form action="{% url 'sub:basic_starter' %}" id="subscription" method="post">
{% csrf_token %}
<fieldset>
<legend><h5><strong>Business Type: </strong> New Business </h5> </legend>
<label>Brand Value Design: N6,180.00
<input type="checkbox" value=" 6179.50" name="services" id="bs1" onclick="subscribe())">
</label><br><br>
<label>Business Development: N6,180.00
<input type="checkbox" value="6180.00" name="services" id="bs2" onclick="subscribe())">
</label><br><br>
<label>Website Design & Dev: N6,180.00
<input type="checkbox" value=" 6180.00" name="services" id="bs3" onclick="subscribe())">
</label><br><br>
<label>Mobile Application : N6,180.00
<input type="checkbox" value="6180.00" name="services" id="bs4" onclick="subscribe())">
</label><br><br>
<label>Maintenance(Host & Domain): N5,450.00
<input type="checkbox" value="5450.00" name="services" id="bs5" onclick="subscribe())">
</label><br><br>
<label>Social Media Management:
<input type="checkbox" value="" name="services" id="bs6" onclick="subscribe())">
</label><br><br>
<input type="text" readonly="readonly" id="total" value="N0.00" ><script>document.getElementById('total').innerHTML=price;</script><br><br>
<input type="submit" value="Subscribe" class="btn btn-success"></a></button><br>
</fieldset>
</form>
</div>
JS
function subscribe(){
let input = document.getElementsByName('services'),
total = 0.00,
form = document.getElementById('subscription');
for (let i = 0; i < input.length; i++) {
if(input[i].checked){
total += parseFloat(input[i].value)
let price = 'N' + total
}
}
document.getElementById('total').value = total.toFixed(3)
}
document.getElementById('subscription').addEventListener('change', subscribe)
Views.py
#login_required
def subscribe(request):
service_list = []
if request.method == 'POST':
sub_form = MembershipForm(request.POST)
if sub_form.is_valid() and sub_form.cleaned_data:
service_list.append(sub_form.data['service_name'])
sub_form.save()
else:
sub_form =MembershipForm()
return render(request, 'sub/subscribe_form.html',{'sub_form':
sub_form})
Url
path('sub', views.subscribe, name='subscribe'),
Forms
class MembershipForm(forms.ModelForm):
class Meta:
model = Services
fields = ('service_name', 'price',)
Models
class Services(models.Model):
package_name = models.CharField(max_length=100)
category = models.CharField(max_length=200)
service_name = models.CharField(max_length=250)
price = models.DecimalField(max_digits=9, decimal_places=2)
def __str__(self):
return self.service_name
class Meta:
unique_together = ('package_name', 'service_name')
class CompanySubscription(models.Model):
company_name = models.ForeignKey(CompanyProfile,
on_delete=models.CASCADE)
services = models.ForeignKey(Services, on_delete=models.CASCADE)
duration = models.CharField(max_length=50)
timestamp= models.DateTimeField(auto_now=True)
def __str__(self):
return self.company_name

If you want to get all checked checkbox value, you have to write below in your view...
#login_required
def subscribe(request):
service_list = []
if request.method == 'POST':
sub_form = MembershipForm(request.POST)
if sub_form.is_valid() and sub_form.cleaned_data:
services_price_list = request.POST.getlist('services[]')
service_list.append(sub_form.data['service_name'])
services_obj = sub_form.save(commit=False)
services_obj.price = sum(services_price_list)
services_obj.save()
else:
sub_form =MembershipForm()
return render(request, 'sub/subscribe_form.html',{'sub_form':
sub_form})

Related

How to get the current object / product from the class based detail view in django?

'''Models Code'''
# Product Model
class Products(models.Model):
name = models.CharField(max_length=50)
img = models.ImageField(upload_to='productImage')
CATEGORY = (
('Snacks','Snacks'),
('Juice','Juice'),
)
category = models.CharField(max_length=50, choices=CATEGORY)
description = models.TextField()
price = models.FloatField()
# Rating Model
class Rating(models.Model):
product = models.ForeignKey(Products, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
stars = models.IntegerField(validators=[MinValueValidator(1),MaxValueValidator(5)], blank=True, null=True)
comment = models.TextField(blank=True,null=True)
''' Views Code '''
class ProductListView(ListView):
model = Products
template_name = 'products.html'
context_object_name ='Products'
class ProductDetailView(LoginRequiredMixin,DetailView):
login_url = '/accounts/login'
model = Products
# Using this function I want to take the rating and comment, but how can I access the cuurent object for which the comment and rating is being send by the user.
def review(request,slug):
star=request.POST.get('rating')
comment=request.POST.get('comment')
user = request.user
productId = request.POST.get('productsid') # How to get the Product
product = Products.objects.get(id=productId)
review = Rating(product=product,user=user,stars=star,comment=comment)
review.save()
return redirect('/')
# Urls code
urlpatterns = [
path('',views.home,name='Home'),
path('products',ProductListView.as_view(),name='Products'),
path('product/<int:pk>',ProductDetailView.as_view(),name='Product-Details'),
path('contact',views.contact,name='Contact'),
path('review',views.review,name='review')
#Templates Code
<form method="POST" action="review">
{% csrf_token %}
<input type="hidden" id="rating-value" name="rating">
<textarea style="margin-top:5px;" class="form-control" rows="3" id="comment" placeholder="Enter your review" name="comment"></textarea>
<button type="submit" style="margin-top:10px;margin-left:5px;" class="btn btn-lg btn-success">Submit</button>
</form>
How to fetch the current object from the deatailed view page in the review function?
I have added the code here. In Product detailed view page it is rendering the page through which I want to take rating and comment for the product . Is there any other way through which I can get the product, user , star, and rating field value and store it in the data base?
I can point out some ways to retrieve the product_id in your review function.
First approach:
You can pass the product_id as a URL parameter. In this case, I hope the review view is called from the product detail page.
So, your url should be something like:
path('review/<int:product_id>', views.review, name="review),
Your view:
def review(request, *args, **kwargs):
star=request.POST.get('rating')
comment=request.POST.get('comment')
user = request.user
productId = kwargs.get('product_id') # change is here
product = Products.objects.get(id=productId)
review = Rating(product=product,user=user,stars=star,comment=comment)
review.save()
return redirect('/')
Your template:
<form method="POST" action="{% url 'review' object.pk %}">
{% csrf_token %}
<input type="hidden" id="rating-value" name="rating">
<textarea style="margin-top:5px;" class="form-control" rows="3" id="comment" placeholder="Enter your review" name="comment"></textarea>
<button type="submit" style="margin-top:10px;margin-left:5px;" class="btn btn-lg btn-success">Submit</button>
</form>
In the template, the object is the object_name you have given to the product object. You can change the object name by adding:
context_object_name = product
in your ProductDetailView.
Second approach:
Pass the product_id as a form data. You can create a hidden input in your template that will contain the product_id as value. For example:
In your template:
<form method="POST" action="review">
{% csrf_token %}
<input type="hidden" id="rating-value" name="rating">
<input type="hidden" name="product_id" value="{{ object.pk }}"> # add a hidden input field
<textarea style="margin-top:5px;" class="form-control" rows="3" id="comment" placeholder="Enter your review" name="comment"></textarea>
<button type="submit" style="margin-top:10px;margin-left:5px;" class="btn btn-lg btn-success">Submit</button>
</form>
Where object is what I mentioned previously.
Then you can retrieve the product_id in view as:
def review(request,slug):
star=request.POST.get('rating')
comment=request.POST.get('comment')
user = request.user
productId = int(request.POST.get('product_id')) # here
product = Products.objects.get(id=productId)
review = Rating(product=product,user=user,stars=star,comment=comment)
review.save()
return redirect('/')

How to upload multiple images with one value in Django

I'm trying to upload multiple images with one single field, in a Django application.
How to do this?
The following files are involved:
upload.html:
<form action="#" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="image_id" placeholder="Image Id">
<input type="file" name="file" multiple>
<button type="submit"> Upload </button>
</form>
Here, the single field image_id is meant to hold 5 images.
views.py:
def multi_image(request):
if request.method == 'POST':
img_id = request.POST.get('image_id')
file = request.FILES.getlist('file')
data_save = Res(image_id = img_id )
data_save.save()
filter_data = Res.objects.filter(image_id= img_id)
if len(filter_data) > 0:
for i in file:
print(i)
Res.objects.create(image= i)
return render(request, 'upload.html', {})
models.py:
class Res(models.Model):
image_id= models.CharField(max_length=10, blank=True, null=True)
image = models.FileField(upload_to='images', blank=True, null=True)
forms.py:
class FileForm(forms.Form):
class Meta:
model = Res
fields = '__all__'

How do I save user ratings in Django database?

This is my first project in Django. I am trying to save rating in Django database but when I click on radio buttons the value doesn't store in database. I have tried solutions of Stack Overflow previously uploaded but none helped me in resolving my issue. I was firstly using RadioSelect in forms.py but still having the same problem.
Here is the code:
Model.py
class Product(models.Model):
title = models.CharField(max_length=120)
brand = models.CharField(max_length=120,default="None")
model = models.CharField(max_length=120,default="None")
slug = models.SlugField(blank=True, unique=True)
category = models.CharField(max_length=120 , default="Phone")
price = models.DecimalField(decimal_places=2, max_digits=20, default=39.99)
class Rating(models.Model):
product=models.ForeignKey(Product,default=None, on_delete=models.PROTECT)
user=models.ForeignKey(User,default=None, on_delete=models.PROTECT)
rating = models.CharField(max_length=120)
Views.py
def add_rating(request,id):
product = get_object_or_404(Product, pk=id)
pro = Product.objects.get(id=id)
if request.method == "POST":
form = RatingForm(request.POST)
if form.is_valid():
product = form.cleaned_data['product']
user = form.cleaned_data['user']
rating = form.cleaned_data['rating']
product = request.POST.get('product', ''),
user = request.POST.get('user', ''),
rating = request.POST.get('rating', ''),
obj = Rating(product=product, user=user, rating=rating)
obj.save()
context = {'obj': obj}
return render(request, 'product/detail.html',context)
else:
form=RatingForm()
return HttpResponse('Please rate the product')
Forms.py
from django import forms
from .models import Rating
class RatingForm(forms.ModelForm):
class Meta:
model = Rating
fields = ('product', 'user','rating')
template.py
<form method="POST" action="{% url 'add_rating' product.id %}">{% csrf_token %}
<ul class="rate-area" style="display:inline;position:absolute">
<input type="radio" id="5-star" name="rating" value="5" /><label for="5- star" title="Amazing">5 stars</label>
<input type="radio" id="4-star" name="rating" value="4" /><label for="4-star" title="Good">4 stars</label>
<input type="radio" id="3-star" name="rating" value="3" /><label for="3-star" title="Average">3 stars</label>
<input type="radio" id="2-star" name="rating" value="2" /><label for="2-star" title="Not Good">2 stars</label>
<input type="radio" id="1-star" name="rating" value="1" /><label for="1-star" title="Bad">1 star</label>
<button type="submit" value="Rate">Rate</button>
</ul>
</form>
You're using a "CharField" on your model while you should be using a "ChoiceField", a ChoiceField would then become a dropdown select.
It would also be easier to use generic editing views; https://docs.djangoproject.com/en/2.2/ref/class-based-views/generic-editing/

how to write join query in django?

I have googled several hours but couldn't understand how to write sql join(raw or ORM) related queries.
Below is my model with two tables sandBox1 and licenseType where they will have common item "email" on which join will be performed
class sandBox1(models.Model):
email = models.EmailField(unique=True)
name = models.CharField(max_length=200)
website = models.TextField(validators=[URLValidator()])
comment = models.TextField(default='-')
gender = models.CharField(max_length=6)
def __str__(self):
return self.email
class licenseType(models.Model):
#1=other, 2=two-wheeler 4=four-wheeler
licenseId = models.IntegerField()
email = models.EmailField()
template file : index.html
<html><form id="form1" method="post" action="{% url "sandbox" %}">
{% csrf_token %}
Name: <input type="text" name="name" >
<br><br>
E-mail: <input type="text" name="email">
<br><br>
Website: <input type="text" name="website" >
<span class="error"></span>
<br><br>
Comment: <textarea name="comment" rows="5" cols="40"></textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male
<hr>Check the license type you have:-<br>
<input type="checkbox" name="license[]" value=2 > 2 wheeler<br>
<input type="checkbox" name="license[]" value=4 > 4 wheeler<br>
<input type="checkbox" name="license[]" value=1 > Other <br>
<br>
<input type="submit" name="submit" value="Submit">
</form>
<div>
{% for obj in sandBoxObj %}
<p>
{{ obj.name }}<br>
{{ obj.email }}<br>
{{ obj.website }}<br>
{{ obj.gender }}<br>
{{ obj.comment }}<br>
{% endfor %}
</div>
</html>
here is a view file that needs correction. I want to show the result of this sql query:
select sandBox1.email,sandBox1.name,licenseType.licenseId from sandBox1
innerjoin licenseType on sandBox1.email=licenseType.email;
View file
def sandbox(request):
template_name='domdom.html'
sandBoxObj = sandBox1.objects.all()
context = { 'sandBoxObj':sandBoxObj }
print request.POST
if request.method == 'POST':
website=request.POST.get('website','')
comment=request.POST.get('comment','')
name=request.POST.get('name','')
gender=request.POST.get('gender','')
email=request.POST.get('email', '')
license=request.POST.getlist('license[]')
for id in license:
licInst = licenseType(licenseId=id,email=email)
licInst.save()
sbinstance = sandBox1(website=website,comment=comment,name=name,gender=gender,email=email)
sbinstance.save()
return render(request,template_name,context)
Raw sql method/ but im still confused on ORM method
def sandbox(request):
template_name='domdom.html'
sandBoxObj = sandBox1.objects.all()
con = sqlite3.connect('/home/user1/PycharmProjects/djrest/invoicesproject/db.sqlite3') #sqlite database file location
cursor = con.cursor()
cursor.execute(''' select todos_sandBox1.email,todos_sandBox1.name,todos_sandBox1.website,todos_sandBox1.comment,todos_sandBox1.gender,todos_licenseType.licenseId from todos_sandBox1
join todos_licenseType on todos_sandBox1.email=todos_licenseType.email
''') #it looks like django appends app name to table eg. appname = todos
result = cursor.fetchall()
#https://www.youtube.com/watch?v=VZMiDEUL0II
context = { 'result':result }
print request.POST
if request.method == 'POST':
website=request.POST.get('website','')
comment=request.POST.get('comment','')
name=request.POST.get('name','')
gender=request.POST.get('gender','')
email=request.POST.get('email', '')
license=request.POST.getlist('license[]')
for id in license:
licInst = licenseType(licenseId=id,email=email)
licInst.save()
sbinstance = sandBox1(website=website,comment=comment,name=name,gender=gender,email=email)
sbinstance.save()
return render(request,template_name,context)
Sorry if this answers the wrong question, but you may want to consider a different data model/ architecture. You are hardcoding SANDBOX1 which implies that there might be multiple Sandboxes and you are listing email fields which aren't tied to the User object. Some basic abstractions may simplify the work. Maybe something like:
from django.contrib.auth.models import User
...
class LicenseTypes(models.Model):
name = models.CharField(max_length=500)
class Customer(models.Model):
name = models.CharField(max_length=500)
license = models.ForeignKey(LicenseType)
class RegisteredUser(models.Model):
customer = models.ForeignKey(Customer, on_delete = models.CASCADE)
user = models.ForeignKey(User)
I like this architecture better because it uses a lot more native django functionality. And makes joins really basic. Check this out in a view:
def django_view(request):
registered_user = RegisteredUser(user=request.user)
#example of how to use the join implicitly/ directly
license = registered_user.customer.license.name

Django Saving Data into Database

I'm having an issue, what I need is to save a part number into a database table. So everytime a user enters the SOSS it should be save in my table. This is my code but is not saving anything, not sure what I'm doing wrong.
manifiestos.html
<form action="{% url 'manifiestos' %}" method="post"> {% csrf_token %}
<p><label for="date"> Date:</label> <input type="text" name="date" value={% now "Y-m-d" %} /> </p>
<p><label for="soss"> SOSS:</label> <input type="text" name="soss" id="soss" /> </p>
<input type="submit" value="Submit" />
</form>
models.py
class manifiestos_bts(models.Model):
soss = models.CharField(max_length=50)
date = models.DateTimeField(null=True, blank=True)
user = models.CharField(max_length=50)
forms.py
class ManifiestosForm(forms.Form):
soss = forms.CharField()
date = forms.DateTimeField()
user = forms.CharField()
html_views
#login_required(login_url='/msr/login')
def manifiestos(request):
if request.method == 'POST':
form = ManifiestosForm(request.POST)
if form.is_valid():
soss = request.POST.get('soss', '')
date = request.POST.get('date', '')
manifiestos_obj = manifiestos_bts(soss= soss, date= date)
manifiestos_obj.save()
return HttpResponseRedirect(reverse('manifiestos'))
else:
form = ManifiestosForm()
return render(request, 'manifiestos.html', {'form': form})
urls.py
url(r'^manifiestos$', html_views.manifiestos, name='manifiestos'),
Thanks for your time :)
If you need more details just let me know.
Your form.is_valid() will fail because you are not passing user from your template. Either remove it from ManifiestosForm or pass it from manifiestos.html