I have a parent model and two children models and I made a view to add multiple children to one parent
but I'm getting confused about making an update view for the parent with all children
this is the form to create multiple children
views.py
def create_day_view(request,pk):
mydate = get_object_or_404(MyDate,pk=pk)
if request.method == 'POST':
length = request.POST.get('length')
sof_zman_1 = request.POST.get('sof_zman_1')
sof_zman_2 = request.POST.get('sof_zman_2')
sof_zman_tefila = request.POST.get('sof_zman_tefila')
ad_image = request.POST.get('ad_image')
day_details = MyDateDetails.objects.create(
date = mydate,
sof_zman_1 = sof_zman_1,
sof_zman_2 = sof_zman_2,
sof_zman_tefila = sof_zman_tefila,
ad_image = ad_image,
)
for file_num in range(0, int(length)):
Image.objects.create(
date = mydate,
image = request.FILES.get(f'images{file_num}')
)
context = {'mydate': mydate}
return render(request, 'luach/create_day.html',context=context)
I'm sharing the template so you will understand how the form works
create_day.html
{% extends 'luach/base.html' %}
{% block content %}
<div class='container'>
<div class="jumbotron myjumbotron">
<div class="p-3 mb-2 bg-light text-center " style="border-radius: 10px;">
<h1 class='title-date text'>{{mydate.hebrew_date}}</h1>
<h4 class='english-date'>{{mydate.english_date}}</h4>
</div>
<label>sof zman 1</label>
<div class="row">
<div class="col">
<input type="time" id="sof_zman_1" class="form-control">
</div>
<div class="col">
</div>
</div>
<label>sof zman 2</label>
<div class="row">
<div class="col">
<input type="time" id="sof_zman_2" class="form-control">
</div>
<div class="col">
</div>
</div>
<label>sof zman tefila</label>
<div class="row">
<div class="col">
<input type="time" id="sof_zman_tefila" class="form-control">
</div>
<div class="col">
</div>
</div>
<br>
<!--<label>ad image</label>
<input type="file" id="ad_image">-->
<br>
<label>Images</label>
<br>
<div class="row">
<div class="col">
<input type="file" multiple>
</div>
<div class="col">
</div>
</div>
<button type="submit" id="saveBtn" class="btn btn-primary mt-4">Save</button>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var files = []
FilePond.registerPlugin(FilePondPluginFileValidateSize);
FilePond.registerPlugin(FilePondPluginFileValidateType);
FilePond.setOptions({
allowMultiple:true,
maxFiles:10,
maxFileSize: '10MB'
})
const inputElement = document.querySelector('input[type="file"]');
const pond = FilePond.create( inputElement, {
acceptedFileTypes:['image/png', 'image/jpeg','image/jpg'],
onaddfile: (err, fileItem) => {
if (!err) {
files.push(fileItem.file)
}
console.log(files)
},
onremovefile: (err, fileItem) => {
const index = files.indexOf(fileItem.file)
if (index > -1) {
files.splice(index, 1)
}
console.log(files)
}
} );
var formData = new FormData();
$(document).on('click', '#saveBtn', function(e) {
formData.append('length', files.length)
formData.append('sof_zman_1', $('#sof_zman_1').val())
formData.append('sof_zman_2', $('#sof_zman_2').val())
formData.append('sof_zman_tefila', $('#sof_zman_tefila').val())
formData.append('ad_image', $('#ad_image').val())
for (var i = 0; i < files.length; i++) {
formData.append('images' + i, files[i])
}
formData.append('csrfmiddlewaretoken', '{{ csrf_token }}')
$.ajax({
type: 'POST',
url: '{% url "day_new" pk=mydate.pk %}',
data: formData,
cache: false,
processData: false,
contentType: false,
enctype: 'multipart/form-data',
success: function (){
//alert('The post has been created!')
window.location.href = "{% url 'date_detail' pk=mydate.pk %}";
},
error: function(xhr, errmsg, err) {
console.log(xhr.status + ":" + xhr.responseText)
}
})
})
})
</script>
{% endblock %}
Related
I am unable to deploy django in Heroku. I think the problem lies with Ajax because all of the pages seems to render in heroku.
Error that I got is:
InvalidCursorName at /incidentReport/general
cursor "_django_curs_140297876031040_sync_1" does not exist
During handling of the above exception (relation "incidentreport_accidentcausation" does not exist LINE 1: ...cidentreport_accidentcausation"."updated_at" FROM "incidentr... ^ ), another exception occurred:
Thank you
HTML
<!-- Page Content -->
<div class="container-fluid">
<!-- Page Title -->
<div class="d-flex bd-highlight">
<div class="pg-title p-2 flex-grow-1 bd-highlight">
<h4>Incident Report</h4>
</div>
</div>
<!-- User Report Table -->
<div class="card shadow mb-5 d-flex ">
<!-- Top Pagination -->
<div class="card-header py-3">
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" href="{% url 'incident_report_general' %}">General</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'incident_report_people' %}">People</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'incident_report_vehicle' %}">Vehicle</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'incident_report_media' %}">Media</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'incident_report_remarks' %}">Remarks</a>
</li>
</ul>
</div>
<div class="card-body">
<div class="table-responsive">
<table>
<form id="form_incidentgeneral" action="{% url 'incident_report_general' %}" enctype="multipart/form-data" method="post" data-acc-url="{% url 'ajax_load_accident' %}">
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputEmail4">Date</label>
{{user_report_form.date}}
</div>
<div class="form-group col-md-6">
<label for="inputPassword4">Time</label>
{{user_report_form.time}}
</div>
</div>
<hr>
<div class="form-row">
<div class="form-group col-md-12">
<label for="inputAddress">Street Address</label>
{{user_report_form.location}}
</div>
</div>
<hr>
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputWeather">Weather</label>
{{inc_gen_form.weather}}
</div>
<div class="form-group col-md-6">
<label for="inputLight">Light</label>
{{inc_gen_form.light}}
</div>
</div>
<!-- ================================= -->
<hr>
<div class="form-row">
<div class="form-group col-md-12">
<label for="inputSeverity">Severity</label>
{{inc_gen_form.severity}}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputAccident">Accident Factor</label>
{{inc_gen_form.accident_factor}}
</div>
<div class="form-group col-md-6">
<label for="inputAccident">Accident Factor Sub Category</label>
{{inc_gen_form.accident_subcategory}}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputAccident">Collision Type</label>
{{inc_gen_form.collision_type}}
</div>
<div class="form-group col-md-6">
<label for="inputAccident">Collision Sub Category</label>
{{inc_gen_form.collision_subcategory}}
</div>
</div>
<!-- ================================= -->
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputCrashType">Crash Type</label>
{{inc_gen_form.crash_type}}
</div>
<div class="form-group col-md-6">
<label for="inputMovement">Movement Code</label>
{{ inc_gen_form.movement_code }}
</div>
</div>
<!-- ================================= -->
<br>
<div class="modal-footer mb-3">
<input type="button" class="btn btn-secondary" data-dismiss="modal"
value="Clear">
<input type="submit" class="btn btn-primary" value="Save">
</div>
</form>
</table>
</div>
</div>
</div>
<!-- End of User Report Table -->
</div>
<!-- End of Page Content -->
AJAX
<script>
$("#id_accident_factor").change(function () {
const url = $("#form_incidentgeneral").attr("data-acc-url"); // get the url of the `load_cities` view
const accidentId = $(this).val(); // get the selected country ID from the HTML input
$.ajax({ // initialize an AJAX request
url: url, // set the url of the request (= /persons/ajax/load-cities/ )
data: {
'accident_factor_id': accidentId // add the country id to the GET parameters
},
success: function (data) {
//console.log(data) // `data` is the return of the `load_cities` view function
$("#id_accident_subcategory").html(data); // replace the contents of the city input with the data that came from the server
let html_data = '<option value="">---------</option>';
data.forEach(function (accident_subcategory) {
html_data += `<option value="${accident_subcategory.id}">${accident_subcategory.sub_category}</option>`
});
console.log(html_data);
$("#id_accident_subcategory").html(html_data);
}
});
});
$("#id_collision_type").change(function () {
const url = $("#form_incidentgeneral").attr("data-acc-url"); // get the url of the `load_cities` view
const collisionId = $(this).val(); // get the selected country ID from the HTML input
$.ajax({ // initialize an AJAX request
url: url, // set the url of the request (= /persons/ajax/load-cities/ )
data: {
'collision_type_id': collisionId // add the country id to the GET parameters
},
success: function (data) {
//console.log(data) // `data` is the return of the `load_cities` view function
$("#id_collision_subcategory").html(data); // replace the contents of the city input with the data that came from the server
let html_data = '<option value="">---------</option>';
data.forEach(function (collision_subcategory) {
html_data += `<option value="${collision_subcategory.id}">${collision_subcategory.sub_category}</option>`
});
console.log(html_data);
$("#id_collision_subcategory").html(html_data);
}
});
});
</script>
Dropdown HTML
<option value="">---------</option>
{% for accsubcategory in acc_subcat %}
<option value="{{ accsubcategory.pk }}">{{ accsubcategory.sub_category }}</option>
{% endfor %}
{% for colsubcategory in col_subcat %}
<option value="{{ colsubcategory.pk }}">{{ colsubcategory.sub_category }}</option>
{% endfor %}
Views
def incident_report_general(request):
if request.method == 'POST':
user_report_form = UserReportForm(request.POST, request.FILES)
inc_gen_form = IncidentGeneralForm(request.POST, request.FILES)
else:
user_report_form = UserReportForm()
inc_gen_form = IncidentGeneralForm()
context = {
'user_report_form': user_report_form,
'inc_gen_form': inc_gen_form,
}
return render(request, 'pages/incident_report.html', context)
def load_accident(request):
accident_factor_id = request.GET.get('accident_factor_id')
collision_type_id = request.GET.get('collision_type_id')
acc_subcat = AccidentCausationSub.objects.filter(accident_factor_id=accident_factor_id).all()
col_subcat = CollisionTypeSub.objects.filter(collision_type_id=collision_type_id).all()
context = {
'acc_subcat': acc_subcat,
'col_subcat': col_subcat
}
return render(request, 'incident/acc_sub_dropdown_list_options.html', context)
Form
class IncidentGeneralForm(forms.ModelForm):
class Meta:
model = IncidentGeneral
fields = '__all__'
def __init__(self, *args, **kwargs):
super(IncidentGeneralForm, self).__init__(*args, **kwargs)
self.fields['accident_factor'].widget.attrs['class'] = 'form-control'
self.fields['accident_subcategory'].widget.attrs['class'] = 'form-control'
self.fields['collision_type'].widget.attrs['class'] = 'form-control'
self.fields['collision_subcategory'].widget.attrs['class'] = 'form-control'
self.fields['weather'].widget.attrs['class'] = 'form-control'
self.fields['light'].widget.attrs['class'] = 'form-control'
self.fields['severity'].widget.attrs['class'] = 'form-control'
self.fields['crash_type'].widget.attrs['class'] = 'form-control'
self.fields['movement_code'].widget.attrs['class'] = 'form-control'
self.fields['accident_subcategory'].queryset = AccidentCausationSub.objects.none()
self.fields['collision_subcategory'].queryset = CollisionTypeSub.objects.none()
if 'accident_factor' in self.data:
try:
accident_factor_id = int(self.data.get('accident_factor'))
self.fields['accident_subcategory'].queryset = AccidentCausationSub.objects.filter(accident_factor_id=accident_factor_id).order_by('accident_factor')
except (ValueError, TypeError):
pass # invalid input from the client; ignore and fallback to empty City queryset
elif self.instance.pk:
self.fields['accident_subcategory'].queryset = self.instance.accident_factor.accident_subcategory_set.order_by('subcategory')
if 'collision_type' in self.data:
try:
collision_type_id = int(self.data.get('collision_type'))
self.fields['collision_subcategory'].queryset = CollisionTypeSub.objects.filter(collision_type_id=collision_type_id).order_by('collision_type')
except (ValueError, TypeError):
pass # invalid input from the client; ignore and fallback to empty City queryset
elif self.instance.pk:
self.fields['collision_subcategory'].queryset = self.instance.collision_type.collision_subcategory_set.order_by('subcategory')
I have up to 4-5 forms, the formsets come in last, I used to javascript to generate more forms at the click of a button. After submission and validation, only the first form data gets saved to the database, the others don't, how can i fix this please?
This is my views.py file
#login_required(login_url='login')
def addItem(request, id) -> render:
res_name = Restro.objects.get(user=request.user)
menuobj = Main.objects.get(restro_name=res_name)
sub_form = createSubCartForm(request.POST)
itemformset = modelformset_factory(Item, form=addItemForm, extra=0, fields=['itname', 'quantity'])
itemform = itemformset(request.POST or None)
vsub_form = createVSubCartForm(request.POST)
vitemformset = modelformset_factory(v_Item, form=addVItemForm, extra=0, fields=['vname'])
vitemform = vitemformset(request.POST or None)
vformset = modelformset_factory(ItemVariation, form=addItemVariationForm, extra=0, fields=['iname', 'varprice', 'quantity'])
vform = vformset(request.POST or None)
if 'nonala' in request.POST:
if request.POST.get('cate1') == 'Non-Ala Carte':
if all([sub_form.is_valid(), itemform.is_valid()]):
global pare
pare = sub_form.save(commit=False)
pare.main_category = Main.objects.get(restro_name=res_name)
pare.save()
for form in itemform:
child = form.save(commit=False)
child.user = request.user
child.sub_category = Sub.objects.get(id=pare.id)
child.save()
return redirect('cust')
elif 'ala' in request.POST:
if request.POST.get('cate2') == 'Ala Carte':
print(request.POST)
context = {
'm_name': menuobj.main_category,
'sub_form': sub_form,
'itemform': itemform,
'vsub_form': vsub_form,
'vitemform': vitemform,
'vform': vform
}
return render(request, 'item_form.html', context)
This is my templates file
<form id="non-alacart" action="" method="post" class="hidden">
{% csrf_token %}
<h3 class="text-center" style="font-weight: bold;">Create Sub Cartegory for <span id="mn">{{ m_name }}</span> Category</h3>
<input type="text" name="cate1" id="main_ca" readonly="readonly">
<div id="item">
<div class="row">
<label class="col-form-label text-center">Sub Category Name<br/>{{sub_form.sname}}</label>
<label class="col-form-label text-center">Sub Category Price<br/>{{sub_form.sprice}}</label>
<br>
<label class="col-form-label text-center">Items<br>
<button id="add" type="button" class="btn btn-light link-success border rounded border-success" id="add" type="button" style="width: 119.5px;">
<i class="la la-plus" style="color: rgb(0,0,0);"></i> Add Item
</button>
</label>
</div>
{% if itemform %}
{{ itemform.management_form }}
<div id='item-list' class="row">
{% for form in itemform %}
<div class="item-form">
{{form}}
</div>
{% endfor %}
</div>
<div id="emp-form" class="hidden">{{ itemform.empty_form }}</div>
{% endif %}
</div>
<div class="row">
<div class="col">
<div class="col d-lg-flex justify-content-lg-center">
<button id="nal" class="btn btn-success link-light border rounded border-success" type="submit" name="nonala" style="width: 119.5px;">Submit</button>
</div>
</div>
</div>
</form>
and the script for generating more forms
const addfield = document.getElementById('add');
const totalnewforms = document.getElementById('id_form-TOTAL_FORMS')
addfield.addEventListener('click', additem);
function additem(event){
if (event){
event.preventDefault();
}
const itemformno = document.getElementsByClassName('item-form')
const itemformcount = itemformno.length//+1
const emp_form_list = document.getElementById('item-list')
const emp_form = document.getElementById('emp-form').cloneNode(true)
emp_form.setAttribute('class', 'item-form row')
emp_form.setAttribute('id', `form-${itemformcount}`)
var p = document.getElementsByTagName('p');
for(var i = 0; i < p.length; i++){
p[i].setAttribute('class', 'col');
};
const regex = new RegExp('__prefix__', 'g')
emp_form.innerHTML = emp_form.innerHTML.replace(regex, itemformcount)
emp_form_list.append(emp_form)
totalnewforms.setAttribute('value', itemformcount+1)
}
for example:
I generated 4 forms and submitted. This is the POST request from the form
<QueryDict: {'csrfmiddlewaretoken': ['FDTYD9gjxr7rQP4truJIkMbcEep0cqNud4meZPDXvQQa2k8vvEZVGo9l7eJHJgVQ'], 'cate1': ['Non-Ala Carte'], 'sname': ['Pizza'], 'sprice': ['3600'], 'form-TOTAL_FORMS': ['4'], 'form-INITIAL_FORMS': ['1'], 'form-MIN_NUM_FORMS': ['0'], 'form-MAX_NUM_FORMS': ['1000'], 'form-0-itname': ['cheese'], 'form-0-quantity': ['6g'], 'form-0-id': ['3'], 'form-1-itname': ['thali'], 'form-1-quantity': ['3g'], 'form-1-id': [''], 'form-2-itname': ['brocoli'], 'form-2-quantity': ['16mg'], 'form-2-id': [''], 'form-3-itname': ['pizza'], 'form-3-quantity': ['1slice'], 'form-3-id': [''], 'form-__prefix__-itname': [''], 'form-__prefix__-quantity': [''], 'form-__prefix__-id': [''], 'nonala': ['']}>
it's reading getting all the form data successfully but when I call save(), only form-0 saves to the database, and after that I can't add any more details, every added one overwites the previously stored details.
I am creating a method of likes for a social network-type website. Currently, I can update the like count by reloading the entire page every time the user likes it. But as in the rest of the websites, it does not have this effect. I would like to eliminate the reload, but I have not been able to. I tried an asynchronous call, but it only works on the first element, and I would not know how to proceed to eliminate this update method in the likes.
HTML for each card:
<div class="col-sm-12 col-md-8 offset-md-2 mt-5 p-0 post-container">
<div class="media pt-3 pl-3 pb-1">
<a href="{% url "users:detail" post.user.username %}">
<img class="mr-3 rounded-circle" height="35" src="{{ post.profile.picture.url }}" alt="{{ post.user.get_full_name }}">
</a>
<div class="media-body">
<p style="margin-top: 5px;">{{ post.user.get_full_name }}</p>
</div>
</div>
<img style="width: 100%;" src="{{ post.photo.url }}" alt="{{ post.title }}">
<p class="mt-1 ml-2" >
<a style="color: #000; font-size: 20px;" id="like_heart" data-id="{{ post.pk }}" data-url="{% url 'posts:likes2' %}">
<i class="{% if request.user in post.likes_users.all %} fas fa-heart {% else %} far fa-heart {% endif %}"
id="success_like"></i>
</a> <i id="value_like">{{ post.likes_users.count }}</i>
</p>
<p class="ml-2 mt-0 mb-2">
<b>{{ post.title }}</b> - <small>{{ post.created }}</small>
</p>
</div>
AJAX call:
$(document).ready(function(){
// ajax for call in post
$("#like_heart").on("click",function(e){
// e.preventDefault();
var id = $(this).data("id");
$.ajax({
// url: 'posts/likes2/',
url: $(this).data("url"),
data: {
'pk': id
},
dataType: 'json',
success: function (data) {
if (data['like']) {
$('#success_like').removeClass("far fa-heart").addClass("fas fa-heart");
}
else {
$('#success_like').removeClass("fas fa-heart").addClass("far fa-heart");
}
var body = '<i id="value_like">' + data['value'] +'</i>'
$('#value_like').html( body );
}
});
})
})
View:
def likes_view(request):
pk = request.GET.get('pk', None)
post_id = Posts.objects.get(pk=pk)
likes_users = User.objects.get(username=request.user)
if post_id.likes_users.filter(username=request.user).exists():
post_id.likes_users.remove(likes_users)
else:
post_id.likes_users.add(likes_users)
data = {'like': post_id.likes_users.filter(username=request.user).exists(), 'value': post_id.likes_users.count()}
return JsonResponse(data)
The issue is about multiple DOM elements having the same id, which not only violates HTML spec but gives you no chance to find desired #value_like.
You can fix it like this, template:
<div class="media pt-3 pl-3 pb-1">
<a href="{% url "users:detail" post.user.username %}">
<img class="mr-3 rounded-circle" height="35" src="{{ post.profile.picture.url }}" alt="{{ post.user.get_full_name }}">
</a>
<div class="media-body">
<p style="margin-top: 5px;">{{ post.user.get_full_name }}</p>
</div>
</div>
<img style="width: 100%;" src="{{ post.photo.url }}" alt="{{ post.title }}">
<p class="mt-1 ml-2" >
<a style="color: #000; font-size: 20px;" class="like-link" data-id="{{ post.pk }}" data-url="{% url 'posts:likes2' %}">
<i class="{% if request.user in post.likes_users.all %} fas fa-heart {% else %} far fa-heart {% endif %} like-toggle" data-id="{{ post.pk }}"></i>
</a> <i class="like-count" data-id="{{ post.pk }}">{{ post.likes_users.count }}</i>
</p>
<p class="ml-2 mt-0 mb-2">
<b>{{ post.title }}</b> - <small>{{ post.created }}</small>
</p>
JS:
$(document).ready(function() {
// ajax for call in post
$(".like-link").on("click", function(e) {
// e.preventDefault();
var id = $(this).data("id");
$.ajax({
// url: 'posts/likes2/',
url: $(this).data("url"),
data: {
'pk': id
},
dataType: 'json',
success: function(data) {
if (data['like']) {
$('.like-toggle[data-id=' + id + ']').removeClass("far fa-heart").addClass("fas fa-heart");
} else {
$('.like-toggle[data-id=' + id + ']').removeClass("fas fa-heart").addClass("far fa-heart");
}
var body = '<i id="value_like">' + data['value'] + '</i>'
$('.like-count[data-id=' + id + ']').html(body);
}
});
})
})
I added data-id attribute to each element that you need to work with. And now I access them using classes and that data-id. Sorry, I couldn't test it myself, but even I had a type, you've got the idea.
I am working on a PRoject and I am stuck on order page.
Here, I want to display list of product images in options tag so that a user can select one image from all or can upload an image functionality of uploading image is working correctly but the selection is not working.
I want to show images to user so that user can select one of them.
models.py
class Product(models.Model):
prod_ID = models.AutoField("Product ID", primary_key=True)
prod_Name = models.CharField("Product Name", max_length=30, null=False)
prod_Desc = models.CharField("Product Description", max_length=2000, null=False)
prod_Price = models.IntegerField("Product Price/Piece", default=0.00)
prod_img = models.ImageField("Product Image", null=True)
class ImageTemplate(models.Model):
temp_id = models.AutoField("Template ID", primary_key=True, auto_created=True)
temp_img = models.ImageField("Template Image", null=False)
class ImageTemplateProductMapping(models.Model):
imageTemp_p_map_id = models.AutoField("Template Image & Product Map ID", primary_key=True, auto_created=True)
temp_id = models.ForeignKey(ImageTemplate, null=False, on_delete=models.CASCADE,
verbose_name="Image Template ID")
prod_id = models.ForeignKey(Product, null=False, on_delete=models.CASCADE, verbose_name="Product Id")
views.py
def order(request, id):
products = Product.objects.all()
ImageTemplateProductsList = []
try:
ImageTemplateProductsMap = ImageTemplateProductMapping.objects.filter(prod_id=id)
ImageTemplateProductsList = [data.temp_id.temp_img for data in
ImageTemplateProductsMap]
except AttributeError:
pass
context = {'products': products,
"ImageTemplateProductsList": ImageTemplateProductsList
}
return render(request, 'user/order.html', context)
order.html
{% extends 'user/layout/userMaster.html' %}
{% block title %}Order{% endblock %}
{% block css %}
form
{
position:relative;
}
.tasksInput
{
margin-right:150px;
}
label
{
vertical-align: top;
}
{% endblock %}
{% block header %}
{% endblock %}
{% block main %}
<div class="container">
<div>
<div class="row rounded mx-auto d-block d-flex justify-content-center">
<button class="btn btn-secondary my-2 mr-1">Custom</button>
<button class="btn btn-secondary my-2 ml-1">Package</button>
</div>
<div class="row">
<div class="col-4">
<div class="card border border-secondary">
<div class="card body mx-2 mt-4 mb-2">
{% for product in products %}
<a id="{{ product.prod_ID }}" class="card-header" style="font-size:5vw;color:black;"
href="{% url 'user-order' product.prod_ID %}">
<h5 class="h5">{{ product.prod_ID }}. {{ product.prod_Name }}</h5></a>
<div class="dropdown-divider"></div>
{% endfor %}
</div>
</div>
</div>
<div class="col-8">
<form>
<div class="card mx-2 my-2 border border-secondary">
<div class="my-2">
<div class="form-group">
<div class="form-group row mx-2">
<label for="quantity"
class="form-control-label font-weight-bold card-header col-4 ml-4 my-auto"
style="background-color:#e3e4e6"><h5>Quantity : </h5></label>
<input id="quantity" class="form-control col-5 mx-2 my-auto" type="number">
</div>
</div>
<div class="form-group">
<div class="form-group row mx-2">
<label for="ImageTemplateProductsList"
class="form-control-label font-weight-bold card-header col-4 ml-4"
style="background-color:#e3e4e6"><h5>Image Template : </h5></label>
<div id="ImageTemplateProductsList" class="mx-2">
<input id="Upload" type="radio" name="ImageSelection" value="Upload"/> Upload an
Image
<input type="file" name="file" class='btn btn-outline-secondary type my-2'>
<br>
<input id="Select" type="radio" name="ImageSelection" value="Select"/> Select
From Templates
<!-- Button trigger modal -->
<input type="button" name="url" style='display: none;'
class='btn btn-outline-secondary type my-2'
value="Choose Template" data-toggle="modal"
data-target="#exampleModalLong">
<!-- Modal -->
<div class="modal fade" id="exampleModalLong" tabindex="-1" role="dialog"
aria-labelledby="exampleModalLongTitle" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Select
Template</h5>
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="d-flex-row justify-content-center modal-body"
style="background:red;">
<div>
<!-- Here I want to display images in select tag to make selection of one from all images but not able to achieve it. -->
<select id="ImageTemplateProductsList1">
{% for IT in ImageTemplateProductsList %}
<option value="{{IT}}"
><img src="{{IT.url}}" height="250" width="400"
class="border border-secondary rounded my-2 mx-3">
</option>
<br>
{% endfor %}
</select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-danger"
data-dismiss="modal">Close
</button>
<button type="button" class="btn btn-outline-secondary">
Select
</button>
</div>
</div>
</div>
</div>
<br>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="row rounded mx-auto d-block d-flex justify-content-center">
<button class="btn btn-success my-2">Place Order</button>
</div>
</div>
</div>
{% endblock %}
{% block js %}
$("document").ready(function(){
$(".type").hide();
$("input:radio").change(function() {
$(".type").hide();
$(this).next("input").show();
});
});
{% endblock %}
urls.py
path('order/<int:id>', views.order, name="user-order"),
I have slightly modified my html template with jquery and changed views a little bit and now it is working for me.
order.html
{% extends 'user/layout/userMaster.html' %}
{% block title %}Order{% endblock %}
{% block css %}
.t {
display: none;
}
img:hover {
opacity:0.8;
cursor: pointer;
}
img:active {
opacity:0.5;
cursor: pointer;
}
input[type=radio]:checked + label > img {
border: 20px solid rgb(228, 207, 94);
}
#dropdown{
height: 50px;
width: 50%;
font-size: 20px;
margin-left: 10px;
margin-top: 3px;
}
{% endblock %}
{% block header %}
{% endblock %}
{% block main %}
<div class="container">
<div>
<div class="row rounded mx-auto d-block d-flex justify-content-center">
<button class="btn btn-secondary my-2 mr-1">Custom</button>
<button class="btn btn-secondary my-2 ml-1">Package</button>
</div>
<div class="row">
<div class="col-4">
<div class="card border border-secondary">
<div class="card body mx-2 mt-4 mb-2">
{% for product in products %}
<a id="{{ product.prod_ID }}" class="card-header" style="font-size:5vw;color:black;"
href="{% url 'user-order' product.prod_ID %}">
<h5 class="h5">{{ product.prod_ID }}. {{ product.prod_Name }}</h5></a>
<div class="dropdown-divider"></div>
{% endfor %}
</div>
</div>
</div>
<div class="col-8">
<form method="POST" enctype="multipart/form-data">
<input type="hidden" id="templateValue" name="templateValue" value=""/>
{% csrf_token %}
<div class="form-group">
<div class="form-group row mx-2">
<label for="ImageTemplateProductsList"
class="form-control-label font-weight-bold card-header col-4 ml-4"
style="background-color:#e3e4e6"><h5>Image Template : </h5></label>
<div id="ImageTemplateProductsList" class="mx-2">
<input id="Upload" type="radio" name="ImageSelection"
class="templateSelection"/> Upload an
Image
<div class="type">
<input type="file" name="image"
class='btn btn-outline-secondary my-2 SelectedImage'>
</div>
<br>
<input type="radio" id="Select" name="ImageSelection" class="templateSelection"
/> Select
From Templates
<div class="type">
{% for IT in ImageTemplateProductsList %}
<input type="radio" name="image2" id="{{IT}}"
value="{{IT}}" class="SelectedImage t"/>
<label for="{{IT}}">
<img src="{{IT.url}}" style="width: 20vw;
height: 20vw;
padding: 2vw;"/>
</label>
<br>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row rounded mx-auto d-block d-flex justify-content-center">
<button type="submit" class="btn btn-success my-2">Place Order</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
$("document").ready(function(){
$(".type").hide();
$("input:radio").on('change', function() {
$(".type").hide();
$(this).next("div").show();
});
$("#templateValue").val('');
$(".templateSelection").on('change', function(){
$("#templateValue").val('');
$("#templateValue").val($(this).attr('id'));
console.log($("#templateValue").val());
});
});
{% endblock %}
I have used hidden field to check whether user is trying to upload the image or select tha image and according to that I am taking the decision that what should I do:
views.py
def order(request, id):
products = Product.objects.all()
ImageTemplateProductsList = []
try:
ImageTemplateProductsMap = ImageTemplateProductMapping.objects.filter(prod_id=id)
ImageTemplateProductsList = [data.temp_id.temp_img for data in
ImageTemplateProductsMap]
except AttributeError:
pass
if request.method == 'POST':
try:
if request.POST['templateValue'] == 'Upload':
if 'image' in request.FILES:
Template_Value1 = request.FILES['image']
fs = FileSystemStorage()
fs.save(Template_Value1.name, Template_Value1)
TemplateValue = Template_Value1.name
elif request.POST['templateValue'] == 'Select':
TemplateValue = request.POST['image2']
else:
pass
except MultiValueDictKeyError:
pass
order_store = Order(product_img=TemplateValue)
order_store.save()
context = {'products': products,
"ImageTemplateProductsList": ImageTemplateProductsList
}
return render(request, 'user/order.html', context)
I create a view which add data from a file. The function will returns two dictionaries, one with data to be saved and one with data on errors.
I would like to send back to template errors only if there is errors.
Thanks for helping.
My actual code send me back an error: Reverse for 'importXLS.views.import_choices' with arguments '(['miss.....
urls.py
path('import_choices/', views.import_choices, name='import-choices'),
# views function
url(r'^data_upload_coa$', views.data_upload_coa, name='data_upload_coa'),
view.py
def data_upload_coa(request): # importing chart of account
if request.method == 'POST':
# Get the form data from the request.
company = request.POST.get('company')
excel_file = {}
excel_file = request.FILES["excel_file"]
# return two dictionaries from coa
accounts, errors = parse_coa(excel_file)
# Add accounts to chart of accounts table
for account in accounts:
# Create a new record with the data if does not exists before.
upload_data = ChartOfAccount.objects.get_or_create(
field_account=account['field_account'],
field_account_libaccount=account['field_account_libaccount'],
field_type=account['field_type'],
field_subtype=account['field_subtype'],
)
# company=company, TO BE ADDED WHEN DEVELOPPING MULTI FIRMS DATA
# Add save success message
messages.success(request, 'Chart of accounts updated')
test = len(errors)
if test == 0:
return redirect(import_choices)
else:
return redirect(import_choices, errors)
else:
# error message
messages.info(request, 'Uploading error')
return redirect(import_choices)
import_choice.html
{% extends 'layouts/base.html' %}
{% load bootstrap3 %}
{% block title %}Import Choices{% endblock %}
{% block heading %}<h3 class="page-header-center">File to import</h3>
{% endblock %}
<hr>
<hr>
{% block page %}
<script> // logic for validation of file
var _validFileExtensions = [".xlsx", ".xls"];
function Validate(oForm) {
var arrInputs = oForm.getElementsByTagName("input");
for (var i = 0; i < arrInputs.length; i++) {
var oInput = arrInputs[i];
if (oInput.type == "file") {
var sFileName = oInput.value;
if (sFileName.length > 0) {
var blnValid = false;
for (var j = 0; j < _validFileExtensions.length; j++) {
var sCurExtension = _validFileExtensions[j];
if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
blnValid = true;
break;
}
}
if (!blnValid) {
alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
return false;
}
}
}
}
return true;
}
</script>
<script> // Recupere le path du fichier
var file = document.getElementById("upload");
file.addEventListener("change", function() {
for (var i = 0; i < file.files.length; i++) {
console.log(file.files[i].name);
}
}, false);
</script>
</br>
</br>
<div class="container">
<div class="panel-heading">
<h4 class="panel-title col-md-6">Please choose a type of file to import:</h4>
</div>
</br>
</br>
<!----------------Accordeon ----------------->
<div class="panel-group col-md-6" id="Choices" >
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title" data-target="#Choice-COA" data-toggle="collapse" data-parent="#Choices">Chart of Accounts</h3>
</div>
<!--accordeon part 1 -->
<div class="panel-collapse collapse" id="Choice-COA">
<div class="panel-body">
<div class="row col-md-4" >
<form method="POST" action="{% url 'data_upload_coa' %}" method="post" id="fileupload" name="fileupload" enctype="multipart/form-data" data-ajax="false" onsubmit="return Validate(this);">
{% csrf_token %}
<table class="table">
<tr>
<td>
<input type="text" placeholder="Enter Company Name " name="company" id="company" required>
</td>
</br>
<td>
<input type="file" title="Upload excel file" name="excel_file" id="myfile" required="required">
</br>
<button type="submit" class="btn btn-primary btn-sm pull-right">Upload</button>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
</div>
</br>
<!--accordeon part 2 -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title" data-target="#import-bv" data-toggle="collapse" data-parent="#Choices">Balance of verification</h3>
</div>
<div class="panel-collapse collapse" id="import-bv">
<div class="panel-body">
<p>To be complete Balance of verification
test</p>
</div>
</div>
</div>
</div>
Result should be:
If errors dictionary is empty go back to import_choice.html
If not: go back to import_choice.html with list in errors shown
in my views. I modified:
if test == 0:
return redirect(import_choices)
else:
return render(request, 'imports/import_choices.html', {"errors": errors})
and in my html file at the end:
{% if errors %}
<div class="panel-body">
<table class="table table-bordered table-hover table-striped col-md-3">
<thead class="thead-dark">
<tr class="text-center">
<th>Accounts with error</th>
</tr>
</thead>
<tbody>
{% for err in errors %}
<tr>
<td scope="row" class="col-md-3">{{ err|capfirst }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}