I've seen other posts about this but still, I'm too dumb :/
So I have this site with products, each product has its unique page-detail where you can leave comments. And now I want to add the possibility to 'star-rate' the product when you write a comment, like in the picture.
Im guessing the first step is to add an Integer field on the "comments model" . But what are the steps from now on ? Im guessing a little JS is needed but i don't rlly know js :/
models.py
class CommentsModel(models.Model):
user = models.ForeignKey(User,on_delete=models.SET_NULL, null=True)
component = models.ForeignKey(ProductsModel,on_delete=models.SET_NULL, null=True)
text = models.TextField(null=False)
date = models.DateTimeField(default=timezone.now)
rating = models.IntegerField(default=0,
validators = [
MaxValueValidator(5),
MinValueValidator(0),
]
)
def __str__(self):
return '%s %s' % (self.component.name, self.user.username)
views.py
def comments_view(request, id):
component = get_object_or_404(ProductsModel, id = id)
comments = CommentsModel.objects.filter(component = component).order_by('-id')
if request.method == 'POST':
comment_form = CommentsForm(request.POST or None)
if comment_form.is_valid():
text = request.POST.get('text')
comment_form = CommentsModel.objects.create(component=component, user=request.user, text=text)
comment_form.save()
return HttpResponseRedirect(component.get_absolute_url())
else:
comment_form = CommentsForm()
context = {'object':component, 'object2':comments, 'comment_form':comment_form}
return render(request, 'templates/comments/comments.html', context)
this is my site with some stars in the template referring how I d like to look and work
forms.py
class CommentsForm(forms.ModelForm):
class Meta:
model = CommentsModel
fields = [
'text',
]
template(just the part with the comments) :
<div class="container">
<form method="post">
{% csrf_token %}
<button type="submit" class="fa fa-star fa-2x my-btn" id="first"></button>
<button type="submit" class="fa fa-star fa-2x my-btn" id="second"></button>
<button type="submit" class="fa fa-star fa-2x my-btn" id="third"></button>
<button type="submit" class="fa fa-star fa-2x my-btn" id="fourth"></button>
<button type="submit" class="fa fa-star fa-2x my-btn" id="fifth"></button>
<div>
{{ comment_form.text|as_crispy_field }}
</div>
{% if request.user.is_authenticated %}
<input type="submit" value="Posteaza" class="btn btn-primary" style="margin-top: 20px; background-color: white; color: black; border-color: white;">
{% else %}
<input type="submit" value="Submit" class="btn btn-outline-succes" style="margin-top: 20px; background-color: white; color: black; border-color: white;" disabled>
{% endif %}
</form>
<div class="main-comment-section" style="margin-top: 10px;">
{{ object2.count }} Comentarii
{% for index in object2 %}
<figure style="padding-top: 10px;">
<blockquote class="blockquote">
<p style="font-weight: 15px;">{{ index.text }}</p>
</blockquote>
<figcaption class="blockquote-footer">
postat de catre <cite title="Source Title">{{ index.user|capfirst}}</cite>
</figcaption>
</figure>
{% endfor %}
</div>
Related
i am trying to develop a django webapp .i want the user to be able to submit other and get redirected to the user's platform where the user sees all his orders . i want a system where the user can make orders and get redirected to a page where will see all his orders
client form:
{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block content %}
{% if user.is_authenticated %}
<div class="container" style="width: 50rem;">
<div class="col-md-10 offset-md-1 mt-5">
<div class="jumbotron">
<!--<h3 id="form-title">Job Specification </h3>-->
<h3 class="display-4" style="text-align: center;">Service Request</h3>
<p id="form-title" style="color: #343a40; text-align: center;">Please provide us with the following information</p>
<hr class="my-4">
<form action="{% url 'clients:add_item' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="row">
<div class="col-md-4">
{{ form.job_name|as_crispy_field }}
</div>
<div class="col-md-8">
{{ form.text_description|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-4">
{{ form.location|as_crispy_field }}
</div>
<div class="col-md-8">
{{ form.address|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-6">
<!--{{ form.phone|as_crispy_field }}-->
<input style="height: 2.5rem;margin: 0 0 8px 0; width: 100%; text-align: center; position: relative; " type="text" name="phone" value="{{ user.details.phone }}" readonly><br>
</div>
<div class="col-md-6">
<input style="height: 2.5rem;margin: 0 0 8px 0; width: 100%; text-align: center; position: relative; " type="text" name="email" value="{{user.email}}" placeholder=" email " readonly><br>
</div>
</div>
<div class="row">
<div class="col-md-6">
{{ form.status|as_crispy_field }}
</div>
<div class="col-md-6" style="height: 2rem;">
<!---{{ form.customer|as_crispy_field }}-->
<input style="height: 2.5rem;margin: 0 0 8px 0; width: 100%; text-align: center; position: relative; top: 30px;" type="text" name="customer" value="{{ user.username}}" placeholder="username" readonly><br>
</div>-->
</div>
<div class="col-md-6">
<input style="height: 2.5rem;margin: 0 0 8px 0; width: 100%; text-align: center; position: relative; " type="text" name="id" value="{{ user.details.id }}" placeholder=" id " readonly><br>
</div>
<h2>
<!-- Your template -->
</h2>
<!--<div class="d-flex justify-content-center mt-3 login_container">
<input class="btn login_btn" type="submit" value="Submit">
</div>-->
<button role="button" class="btn btn-danger btn-lg">Submit</button>
</form>
</div>
</div>
</div>
{{ form.errors }}
{% else %}
<div class="container" style="width: 20rem; background-color: #6e1a52; margin-top: 70px; height: 20rem;" >
<div class="col-md-10 offset-md-1 mt-5" >
<!--<div class="jumbotron">
<h3 id="form-title" style="text-align: center;">Please login to enable you request the service you want</h3>-->
<h3 class="display-44" style="text-align: center; font-size: 22px; margin-top: 50px; color: #343a40;">request service</h3>
<p id="form-title" >Please login to enable you request the service you want</p>
<a href="{% url 'accounts:login' %}"
style="font-size: 24px; text-align: center; text-decoration: none;" >Login</a>
<!-- <a action="{% url 'profession:add_item' %}" role="button" class="btn btn-primary btn-lg">Submit</a>-->
</div>
</div>
{% endif %}
view file for client view:
#login_required
def insert_ClientJob(request):
if request.method == 'POST':
form = ClientJobForms(request.POST)
user_id=request.POST.get('id')
if form.is_valid():
product = form.save(commit=False)
#customer = ClientJob.objects.create(customer=product)
#product.customer =customer
product.save()
messages.success(request ,"successful")
return redirect('profession:user',user_id)
else:
form = ClientJobForms()
return render(request ,'job_request.html' ,{'form': form})
url file client url:
om django.urls import path
from .views import *
from .import views
app_name = 'clients'
urlpatterns = [
path('add_item/', views.insert_ClientJob ,name='add_item'),
]
model file client model:
from django.db import models
# Create your models here.
class ClientJob(models.Model):
STATUS = (
('Pending', 'Pending'),
#('On-going', 'On-going'),
('Completed', 'Completed'),
)
customer = models.ForeignKey('accounts.Customer', null=True,blank=True, on_delete= models.SET_NULL,related_name='client')
job_name = models.CharField(max_length=50,unique =False)
text_description = models.CharField(max_length=150,null=True)
location = models.ForeignKey('accounts.Area' ,on_delete =models.CASCADE)
address = models.CharField(max_length=200,unique =False)
phone =models.CharField(max_length=15,unique =False)
email = models.EmailField(unique = False)
date_created = models.DateTimeField(auto_now_add=True, null=True)
status = models.CharField(max_length=200, null=True, choices=STATUS,default='Pending')
def __str__(self):
return self.job_name
class Meta:
verbose_name_plural = "Client Job"
form file client form:
from django.db.models import fields
from django.forms import ModelForm
from django import forms
from django.contrib.auth.models import User
from .models import *
class ClientJobForms(ModelForm):
class Meta:
model = ClientJob
fields = ['job_name','text_description','location','address','phone','email','status','customer']
#fields ="__all__"
def __init__(self, *args, **kwargs):
super(ClientJobForms, self).__init__(*args, **kwargs)
self.fields['location'].empty_label ='Your location'
admin file client admin:
list_display = ('id','job_name','text_description','location','address','phone','email','date_created','status','customer')
admin.site.register(ClientJob ,ClientJobAdmin)
accounts model:
class Area(models.Model):
area_code = models.CharField(max_length=7)
location = models.CharField(max_length=100)
def __str__(self):
return self.location
class Meta:
verbose_name_plural = "Area"
class Customer(models.Model):
user = models.OneToOneField(User,null=True,blank=True, on_delete= models.SET_NULL,related_name='details')
address = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=15, null=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return str(self.user)
no form errors are showing up in my HTML template when the form is invalid. The form is placed within a carousel incase that's relevant.
I'm calling out individual form elements instead of rendering as {{form.as_p}}, errors where showing when this was the case.
The last item in the carousel is the password and if I leave this blank it will show a pop out that says "please fill in this field" but nothing more than that and only for that one field.
Views.py
def collapsecard(request):
if request.method == 'POST':
create_user_form = CreateUserForm(request.POST)
safezone_form = SafezoneForm(request.POST)
if create_user_form.is_valid() and safezone_form.is_valid():
user = create_user_form.save()
safezone = safezone_form.save(commit=False)
safezone.userid = user
safezone.useremail = user.email
safezone.save()
user = authenticate(username=create_user_form.cleaned_data['username'],
password=create_user_form.cleaned_data['password1'],
)
login(request,user)
api_key = 'XYZ'
api_secret = 'XYZ'
id = 'XYZ'
mailjet = Client(auth=(api_key, api_secret))
data = {
'Email': safezone.useremail,
'Action': "addnoforce"
}
result = mailjet.contactslist_managecontact.create(id=id, data=data)
print
result.status_code
print
result.json()
return redirect('safezoneaddedpage')
return render(request, 'V2maparonno_create_safe_zoneV2.html',
{'create_user_form': create_user_form, 'safezone_form': safezone_form})
else:
create_user_form = CreateUserForm()
safezone_form = SafezoneForm()
print(create_user_form.errors)
print(safezone_form.errors)
return render(request, 'V2maparonno_create_safe_zoneV2.html',
{'create_user_form': create_user_form, 'safezone_form': safezone_form})
Extract from HTML
<form action="" method="POST" class="form-control">
{% csrf_token %}
<div id="carouselExampleIndicators" class="carousel slide" data-interval="false" style="width: 100%">
<ol class="carousel-indicators">
<li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="3"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="4"></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<div class="carousel-caption">
<h5>Drag the marker over your home</h5>
<div class="longlatinput">
{{ safezone_form.latitudecentre }}{{ safezone_form.longitudecentre }}
</div>
<button class="btn btn-sm btn-outline-primary" type="button" data-slide-to="1" data-target="#carouselExampleIndicators">Next</button>
</div>
</div>
<div class="carousel-item">
<div class="carousel-caption">
<h5>Give your safezone a name</h5>
<div class="form-inputs">
{{ safezone_form.name }}
</div>
<div class="name_space">
<button class="btn btn-sm btn-outline-primary" type="button" data-slide-to="2" data-target="#carouselExampleIndicators">Next</button>
</div>
</div>
</div>
<div class="carousel-item">
<div class="carousel-caption">
<h5>What email address should we send an alert to?</h5>
<div class="form-inputs">
{{create_user_form.email}}
</div>
<button class="btn btn-sm btn-outline-primary" type="button" data-slide-to="3" data-target="#carouselExampleIndicators">Next</button>
</div>
</div>
<div class="carousel-item">
<img src="https://pupaprojectawsbucket.s3.eu-west-2.amazonaws.com/Screenshot+2021-05-04+at+20.36.09.png" alt="..." style="width: 100%; height: 200px;">
<div class="carousel-caption">
<h5>Create your username</h5>
<div class="form-inputs">
{{create_user_form.username}}
</div>
<button class="btn btn-sm btn-outline-primary" type="button" data-slide-to="4" data-target="#carouselExampleIndicators">Next</button>
</div>
</div>
<div class="carousel-item">
<div class="carousel-caption">
<h5>Finally, set a password</h5>
<div class="form-inputs">
{{create_user_form.password1}}
</div>
<input class="btn btn-success" type="submit" name="Submit" id="reset-btn">
<div class="disclaimer"><p>By clicking submit you agree to receiving email alerts.</p></div>
</div>
</div>
</div>
</div>
</form>
**<div class = card>
Errors
{{safezone_form.errors.name}}
{{create_user_form.errors.email}}
{{create_user_form.errors.username}}
{{create_user_form.errors.password1}}
</div>**
Forms.py
password2 = None
email = forms.EmailField(widget=forms.EmailInput(attrs={"placeholder": "michael#gmail.com"}))
username = forms.CharField(widget=forms.TextInput(attrs={"placeholder": "JohnSmith078"}))
password1 = forms.CharField(widget=forms.PasswordInput(attrs={"placeholder": "8+ characters"}))
class Meta:
model = User
fields = ['username', 'email', 'password1']
def clean_password1(self):
password1 = self.cleaned_data.get('password1')
try:
password_validation.validate_password(password1, self.instance)
except forms.ValidationError as error:
self.add_error('password1', error)
return password1
class SafezoneForm(forms.ModelForm, admin.ModelAdmin):
name = forms.CharField(label='Safezone name',widget=forms.TextInput
(attrs={'id': 'name', 'label': 'Name of Safezone', 'class': 'form-inputs',"placeholder": "Mum's house"}))
latitudecentre = forms.FloatField(label='Safezone Latitude',widget=forms.TextInput
(attrs={'id': 'latitudecentre','class': 'form-inputs',"placeholder": "Latitude"}))
longitudecentre = forms.FloatField(label='Safezone Longitude',widget=forms.TextInput
(attrs={'id': 'longitudecentre','class': 'form-inputs',"placeholder": "Longitude"}))
class Meta:
model = Safezone
fields = ['name', 'longitudecentre', 'latitudecentre']
Your errors don't show because you're redirecting to another page if your forms are not valid.
if create_user_form.is_valid() and safezone_form.is_valid():
...
return redirect('safezoneaddedpage')
return redirect('safezoneaddedpage') # detelete this, here you must not redirect to another page, but render the same template.
and add this:
return render(request, 'V2maparonno_create_safe_zoneV2.html',
{'create_user_form': create_user_form, 'safezone_form': safezone_form})
I want to search for products in my app by their categories, retrieving data from firebase database. The search works but doesn't display the products and I can't figure out what other context is to be passed. I'm new to Django so any help would be appreciated.
here's my Welcome.html:
<form class="form-inline my-2 my-lg-0" method="get" action="/postsign" id="s">
{% csrf_token %}
<input class="form-control mr-sm-2" type="search" value="{{ category }}" placeholder="Search by category" aria-label="Search" name="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" onclick="location.href='/postsign/?category={{ category }}'" form="s">Search</button>
</form>
</div>
</nav>
<div class="container">
<div class="col-md-4">
<div class="cards">
{% for product in category %}
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="{{ product.image }}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{ product.pname }}</h5>
<p class="price">{{ product.price }}</p>
<p class="card-text">{{ product.description }}</p>
<button class="btn btn-primary cart">Add to cart</button>
<button class="btn btn-primary" onclick="location.href='{% url 'productView' %}'">View product</button>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
Here's the views:
def postsign(request):
if request.method == 'GET' and 'csrfmiddlewaretoken' in request.GET:
search = request.GET.get('Search')
search = search.lower()
timestamps = database.child("Products").shallow().get().val()
pcategory = []
for i in timestamps:
category = database.child("Products").child(i).child("category").get().val()
category = str(category)+"$"+str(i)
pcategory.append(category)
matching =[str(string) for string in pcategory if search in string.lower()]
s_category = []
s_id = []
for i in matching:
category,ids=i.split("$")
s_category.append(category)
s_id.append(ids)
data = services.get_products()
return render(request, "Welcome.html",{'category':s_category})
Here's how my database looks:
products{
timestamp{
name:...
category:...
}
timestamp{
name:..
category:...
...
I have problem. My template don't show my value from db.
I think that I don't have defined model UserProduct in views.py in function product.
wievs.py
def index(request):
context = {
'products': Product.objects.order_by('category').filter(is_published=True)
}
return render(request, 'offers/products.html', context)
def userproduct(request):
context = {
'userproduct': UserProduct.objects.filter(user_id=request.user.id),
}
return render(request, 'offers/userproducts.html', context)
def product(request, product_id):
product = get_object_or_404(Product, pk=product_id)
context = {
'product': product,
}
return render(request, 'offers/product.html', context)
models.py
class Product(models.Model):
product_name = models.CharField(max_length=100)
category = models.CharField(max_length=50)
weight = models.FloatField()
description = models.TextField(blank=True)
photo = models.ImageField(upload_to='photos/%Y/%m/%d/')
is_published = models.BooleanField(default=True)
list_date = models.DateField(default=datetime.now, blank=True)
def __str__(self):
return self.product_name
class UserProduct(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
product_name = models.ForeignKey(Product, on_delete=models.CASCADE)
price = models.FloatField()
is_published = models.BooleanField(default=True)
list_date = models.DateField(default=datetime.now, blank=True)
def __str__(self):
return str(self.user.username) if self.user.username else ''
offers/product.html
<div class="p-4">
<p class="lead">
{% if user.is_authenticated %}
<span class="mr-1">
<p>Price</p></span>
<p class="colores lead font-weight-bold">{{ product.price }} £</p>
{% endif %}
<p >Description</p>
<p class="colores lead font-weight">{{ product.description }}</p>
<p class="colores lead font-weight-bold">Weight: {{ product.weight }}kg</p> </p>
{% if user.is_authenticated %}
<form class="d-flex justify-content-left">
<!-- Default input -->
<input type="number" value="1" aria-label="Search" class="form-control" style="width: 100px">
<button class="btn send-click btn-md my-0 p" type="submit">Add to cart
<i class="fas fa-shopping-cart ml-1"></i>
</button>
</form>
{% endif %}
</div>
Value product.price does not show.
The idea is that each user will have a different product price.
That's because your Product model has no price field; What you have is userproduct_set as a reverse foreign key relationship from the UserProduct model.
So you may have multiple price for one Product instance.
You can use the following code to show all the available prices for your product:
<div class="p-4">
<p class="lead">
{% if user.is_authenticated %}
<span class="mr-1">
<p>Price</p></span>
{% for userproduct in product.userproduct_set.all %}
<p class="colores lead font-weight-bold">{{ userproduct.price }} £</p>
{% endfor %}
{% endif %}
<p>Description</p>
<p class="colores lead font-weight">{{ product.description }}</p>
<p class="colores lead font-weight-bold">Weight: {{ product.weight }}kg</p> </p>
{% if user.is_authenticated %}
<form class="d-flex justify-content-left">
<!-- Default input -->
<input type="number" value="1" aria-label="Search" class="form-control" style="width: 100px">
<button class="btn send-click btn-md my-0 p" type="submit">Add to cart
<i class="fas fa-shopping-cart ml-1"></i>
</button>
</form>
{% endif %}
</div>
Read more about them in the docs.
Edit
As you mentioned in the comments, you want to find out the price assigned to the current logged in user, if the user is logged in and show weight and description even if the user is not logged in. So you need:
def product(request, product_id):
product = get_object_or_404(Product, pk=product_id)
user_product = None
if request.user.is_authenticated:
user_product = UserProduct.objects.filter(product_name_id=product_id, user=request.user)
if user_product:
user_product = user_product.first()
context = {
'product': product,
'user_product': user_product,
}
return render(request, 'offers/product.html', context)
and your template as well:
<div class="p-4">
<p class="lead">
{% if user.is_authenticated and user_product %}
<span class="mr-1">
<p>Price</p></span>
<p class="colores lead font-weight-bold">{{ user_product.price }} £</p>
{% endif %}
<p>Description</p>
<p class="colores lead font-weight">{{ product.description }}</p>
<p class="colores lead font-weight-bold">Weight: {{ product.weight }}kg</p> </p>
{% if user.is_authenticated and user_product %}
<form class="d-flex justify-content-left">
<!-- Default input -->
<input type="number" value="1" aria-label="Search" class="form-control" style="width: 100px">
<button class="btn send-click btn-md my-0 p" type="submit">Add to cart
<i class="fas fa-shopping-cart ml-1"></i>
</button>
</form>
{% endif %}
</div>
I am trying to edit multiple rows of data in a model via formsets. In my rendered form, I use javascript to delete (hide and assign DELETE) rows, and then save changes with post.
My view:
def procedure_template_modification_alt(request, cliniclabel, template_id):
msg = ''
clinicobj = Clinic.objects.get(label=cliniclabel)
template_id = int(template_id)
template= ProcedureTemplate.objects.get(templid = template_id)
formset = ProcedureModificationFormset(queryset=SectionHeading.objects.filter(template = template))
if request.method == 'POST':
print(request.POST.get)
# Create a formset instance with POST data.
formset = ProcedureModificationFormset(request.POST)
if formset.is_valid():
print("Form is valid")
instances = formset.save(commit=False)
print(f'instances:{instances}')
for instance in instances:
print(f'Instance: {instance}')
instance.template = template
instance.save()
msg = "Changes saved successfully."
print("Deleted forms:")
for form in formset.deleted_forms:
print(form.cleaned_data)
else:
print("Form is invalid")
print(formset.errors)
msg = "Your changes could not be saved as the data you entered is invalid!"
template= ProcedureTemplate.objects.get(templid = template_id)
headings = SectionHeading.objects.filter(template = template)
return render(request, 'procedures/create_procedure_formset_alt.html',
{
'template': template,
'formset': formset,
'headings': headings,
'msg': msg,
'rnd_num': randomnumber(),
})
My models:
class ProcedureTemplate(models.Model):
templid = models.AutoField(primary_key=True, unique=True)
title = models.CharField(max_length=200)
description = models.CharField(max_length=5000, default='', blank=True)
clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE)
def __str__(self):
return f'{self.description}'
class SectionHeading(models.Model):
procid = models.AutoField(primary_key=True, unique=True)
name = models.CharField(max_length=200)
default = models.CharField(max_length=1000)
sortorder = models.IntegerField(default=1000)
fieldtype_choice = (
('heading1', 'Heading1'),
('heading2', 'Heading2'),
)
fieldtype = models.CharField(
choices=fieldtype_choice, max_length=100, default='heading1')
template = models.ForeignKey(ProcedureTemplate, on_delete=models.CASCADE, null=False)
def __str__(self):
return f'{self.name} [{self.procid}]'
My forms:
class ProcedureCrMetaForm(ModelForm):
class Meta:
model = SectionHeading
fields = [
'name',
'default',
'sortorder',
'fieldtype',
'procid'
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['name'].widget.attrs.update({'class': 'form-control'})
self.fields['default'].widget.attrs.update({'class': 'form-control'})
self.fields['sortorder'].widget.attrs.update({'class': 'form-control'})
self.fields['fieldtype'].widget.attrs.update({'class': 'form-control'})
ProcedureCreationFormset = formset_factory(ProcedureCrMetaForm, extra=3)
ProcedureModificationFormset = modelformset_factory(SectionHeading, ProcedureCrMetaForm,
fields=('name', 'default', 'sortorder','fieldtype', 'procid'),
can_delete=True,
extra=0
# widgets={"name": Textarea()}
)
The template:
{% block content %} {% load widget_tweaks %}
<div class="container">
{% if user.is_authenticated %}
<div class="row my-1">
<div class="col-sm-2">Name</div>
<div class="col-sm-22">
<input type="text" name="procedurename" class="form-control" placeholder="Enter name of procedure (E.g. DNE)"
value="{{ template.title }}" />
</div>
</div>
<div class="row my-1">
<div class="col-sm-2">Description</div>
<div class="col-sm-22">
<input type="text" name="proceduredesc" class="form-control" placeholder="Enter description of procedure (E.g. Diagnostic Nasal Endoscopy)"
value="{{ template.description }}" />
</div>
</div>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %} {{ formset.management_form }}
<div class="row mt-3">
<div class="col-sm-1">Select</div>
<div class="col-sm-6">Heading</div>
<div class="col-sm-8">Default (Normal description)</div>
<div class="col-sm-2">Sort Order</div>
<div class="col-sm-4">Type</div>
<div class="col-sm-2">Action</div>
</div>
{% for form in formset %}
<div class="row procrow" id="row{{ forloop.counter0 }}">
<div class="" style="display: none;">{{ form.procid }}</div>
<div class="col-sm-6">
{{ form.name }}
</div>
<div class="col-sm-8">
<div class="input-group">
{{ form.default }}
</div>
</div>
<div class="col-sm-2">
<div class="input-group">
{{ form.sortorder }}
</div>
</div>
<div class="col-sm-4">
<div class="input-group">
{{ form.fieldtype }}
</div>
</div>
<div class="col-sm-2">
<div class="input-group">
<div class="input-group-append">
<button id="add{{ forloop.counter0 }}" class="btn btn-success add-row">+</button>
</div>
<div class="input-group-append">
<button id="del{{ forloop.counter0 }}" class="btn btn-danger del-row">-</button>
</div>
</div>
</div>
</div>
{% endfor %} {% endif %}
<div class="row my-3">
<div class="col-sm-8"></div>
<div class="col-sm-8">
<div class="input-group">
<div class="input-group-append mx-1">
<button id="save_report" type="submit" class="btn btn-success"><i class="fal fa-shield-check"></i>
Save Report Format</button>
</div>
<div class="input-group-append mx-1">
<button id="save_report" type="button" class="btn btn-danger"><i class="fal fa-times-hexagon"></i>
Cancel</button>
</div>
</div>
</div>
<div class="col-sm-8"></div>
</div>
<div>
{% for dict in formset.errors %} {% for error in dict.values %} {{ error }} {% endfor %} {% endfor %}
</div>
</form>
</div>
{% endblock %}
My data is displayed as below (Screenshot). I make changes with javascript when the delete button is pressed, so that the html becomes like this:
<div class="row procrow" id="row2" style="display: none;">
<div class="" style="display: none;"><input type="hidden" name="form-2-procid" value="25" id="id_form-2-procid"></div>
<div class="col-sm-6">
<input type="text" name="form-2-name" value="a" maxlength="200" class="form-control" id="id_form-2-name">
</div>
<div class="col-sm-8">
<div class="input-group">
<input type="text" name="form-2-default" value="v" maxlength="1000" class="form-control" id="id_form-2-default">
</div>
</div>
<div class="col-sm-2">
<div class="input-group">
<input type="number" name="form-2-sortorder" value="1000" class="form-control" id="id_form-2-sortorder">
</div>
</div>
<div class="col-sm-4">
<div class="input-group">
<select name="form-2-fieldtype" class="form-control" id="id_form-2-fieldtype">
<option value="heading1" selected="">Heading1</option>
<option value="heading2">Heading2</option>
</select>
</div>
</div>
<div class="col-sm-2">
<div class="input-group">
<div class="input-group-append">
<button id="add2" class="btn btn-success add-row">+</button>
</div>
<div class="input-group-append">
<button id="del2" class="btn btn-danger del-row">-</button>
</div>
</div>
</div>
<input type="checkbox" name="form-2-DELETE" id="id_form-2-DELETE" checked=""></div>
On submitting the data, I get the following output, and data does not reflect the deletion I did. It displays the same thing again. There are no errors. But my edited data is not being saved.
Output:
<bound method MultiValueDict.get of <QueryDict: {'csrfmiddlewaretoken': ['ka3avICLigV6TaMBK5a8zeVJlizhtsKW5OTDBLlYorKd7Iji9zRxCX2vvjBv6xKu'], 'form-TOTAL_FORMS': ['3'], 'form-INITIAL_FORMS': ['3'], 'form-MIN_NUM_FORMS': ['0'], 'form-MAX_NUM_FORMS': ['1000'], 'form-0-procid': ['23'], 'form-0-name': ['External ear canal'], 'form-0-default': ['Bilateral external ear canals appear normal. No discharge.'], 'form-0-sortorder': ['100'], 'form-0-fieldtype': ['heading1'], 'form-1-procid': ['24'], 'form-1-name': ['Tympanic membrane'], 'form-1-default': ['Tympanic membrane appears normal. Mobility not assessed.'], 'form-1-sortorder': ['500'], 'form-1-fieldtype': ['heading1'], 'form-2-procid': ['25'], 'form-2-name': ['a'], 'form-2-default': ['v'], 'form-2-sortorder': ['1000'], 'form-2-fieldtype': ['heading1'], 'form-2-DELETE': ['on']}>>
Form is valid
instances:[]
Deleted forms:
{'name': 'a', 'default': 'v', 'sortorder': 1000, 'fieldtype': 'heading1', 'procid': <SectionHeading: a [25]>, 'DELETE': True}
You actually need to delete the instances: Loop through the formsets' deleted_objects property after you called saved(commit=False) and delete them.