I have a table in a HTML template that displays all instances of a django model. on each row of the template I have an edit button that looks up the primary key of each instance, and by clicking that button I want all the fields in the model instance to be populated in a modal by using ajax. After that I want to be able to edit the data and use ajax to send the edited data back to the database.
I have been searching all over the web and found this post that is exactly what I need, but I still can't get it to work. Any help would be greatly appreciated.
jQuery code
var modalDiv = $("#modal-div");
$(".open-modal").on("click", function() {
console.log("button clicked");
var url = $(this).attr('data-url').replace('/', '');
console.log("url:",url); // this returns my customer number but is not used in the code below
$.ajax({
url: $(this).attr("data-url"),
type: 'get',
success: function(data) {
console.log("success");
modalDiv.html(data);
$("#myEdit").modal(); //#myEdit is the ID of the modal
},
error : function() {
console.log("Error: this did not work"); // provide a bit more info about the error to the console
}
});
});
a tag in form
<a class="btn open-modal" data-url="{% url 'dashboard:customer_update' kunde.kundenr %}">Edit</a>
Needless to say, I keep receiving the error console.log message.
Below is the complete codebase.
Model:
class Kunde(models.Model):
avd = [('610','610'), ('615', '615'), ('620', '620'), ('625', '625'), '630', '630'), ('635', '635'),('640', '640'),('645', '645'), ('650', '650'), ('655', '655')]
avdeling = models.CharField(max_length=3, choices=avd)
selskap = models.CharField(max_length=50, unique=True)
kundenr = models.CharField('Kundenummer', max_length=15, unique=True, primary_key=True)
gatenavn = models.CharField(max_length=50,)
postnr = models.CharField('Postnummer', max_length=4)
poststed = models.CharField(max_length=30)
kommune = models.CharField(max_length=30)
timestamp = models.DateField(auto_now_add=True)
updated = models.DateField(auto_now=True)
def get_absolute_url(self):
return reverse("dashboard:index")
def __str__(self):
return self.selskap
class Meta:
ordering = ['selskap']
Urls
app_name = "dashboard"
urlpatterns = [
path('', views.dashboard, name='index'),
path('', views.customer_list, name='customer_list'),
url(r'^(?P<kundenummer>[0-9]+)$', views.customer_update, name='customer_update'),
]
Views:
main view to display the table
def dashboard(request):
template = 'dashboard/index.html'
if request.user.groups.filter(name__in=['Vest']).exists():
queryset = Kunde.objects.filter(Q(avdeling='630') | Q(avdeling='635')).all()
elif request.user.groups.filter(name__in=['Nord']).exists():
queryset = Kunde.objects.filter(Q(avdeling='610') | Q(avdeling='615') | Q(avdeling='620')).all()
elif request.user.groups.filter(name__in=['Øst']).exists():
queryset = Kunde.objects.filter(Q(avdeling='660') | Q(avdeling='655') | Q(avdeling='650')).all()
elif request.user.groups.filter(name__in=['Sør']).exists():
queryset = Kunde.objects.filter(Q(avdeling='640') | Q(avdeling='645')).all()
elif request.user.groups.filter(name__in=['Nord-Vest']).exists():
queryset = Kunde.objects.filter(Q(avdeling='625')).all()
else:
queryset = Kunde.objects.all()
context = {
"object_list": queryset,
}
return render(request, template, context)
view to display the modal with
def customer_update(request, kundenr=None):
template = 'dashboard/index.html'
instance = get_object_or_404(Kunde, kundenr=kundenr)
context={
'selskap': instance.selskap,
'instance': instance,
}
return render(request, template, context)
HTML table
<div class"container-table" style="overflow-x:auto;">
<table class="display table table-bordered table-condensed" id="table_kundeliste">
<thead class="thead-inverse">
<tr>
<th>Avdeling</th>
<th>Selskap</th>
<th>Kundenr.</th>
<th>Poststed</th>
<th>Kommune</th>
<th>Rediger</th>
</tr>
</thead>
<tbody>
{% for kunde in object_list %}
<tr>
<td> {{ kunde.avdeling }} </td>
<td> {{ kunde.selskap }} </td>
<td> {{ kunde.kundenr }} </td>
<td> {{ kunde.poststed }} </td>
<td> {{ kunde.kommune }} </td>
<td>
<a class="btn open-modal" data-url="{% url 'dashboard:customer_update' kunde.kundenr %}">Edit</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
this part include modal in html
<div id="modal-div" class="modal-div">
{% include 'dashboard/customer-modal.html' %}
</div>
this is the modal template itself
<div class="modal fade" id="myEdit" role="dialog">
<div class="modal-dialog">
<form class="well contact-form" method="post" action="{% url dashboard:'customer_update'}">
{% csrf_token %}
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<label for="avdeling">Avdeling:</label>
<input type="text" class="form-control" required="" name="avdeling" value="{{ instance.avdeling }}" id="avdeling">
<label for="selskap">Selskap:</label>
<input type="text" class="form-control" required="" name="selskap" value="{{ instance.selskap }}" id="selskap">
<label for="kundenummer">Kundenummer:</label>
<input type="text" class="form-control" required="" name="kundenummer" value="{{ instance.kundenr }}" id="kundenummer">
<label for="gatenavn">Gatenavn:</label>
<input type="text" class="form-control" required="" name="gatenavn" value="{{ instance.gatenavn }}" id="gatenavn">
<label for="postnummer">Postnummer:</label>
<input type="text" class="form-control" required="" value="{{ instance.postnr }}" name="postnummer" id="postnummer" >
<label for="poststed">Poststed:</label>
<input type="text" class="form-control" required="" value="{{ instance.poststed }}" name="poststed" id="poststed" >
<label for="kommune">Kommune:</label>
<input type="text" class="form-control" required="" value="{{ instance.kommune }}" name="kommune" id="kommune" >
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-default">Valider</button>
<button value="" type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</form>
Related
I have this view with two forms.
def anunciocreateview(request):
anuncio_form = AnuncioForm(request.POST or None)
producto_form = ProductoForm(request.POST or None)
if request.method == "POST":
if all([anuncio_form.is_valid(), producto_form.is_valid(), imagen_form.is_valid()]):
anuncio = anuncio_form.save(commit=False)
anuncio.anunciante = request.user
anuncio.save()
producto = producto_form.save(commit=False)
producto.anuncio = anuncio
producto.save()
return HttpResponse(status=204, headers={'HX-Trigger' : 'eventsListChanged'})
else:
anuncio_form = AnuncioForm()
producto_form = ProductoForm()
context = {
'anuncio_form' : anuncio_form,
'producto_form' : producto_form,
}
return render(request, 'buyandsell/formulario.html', context)
This view works OKAY; it allows the user to create instances of both models with the correct relation. I'm trying to add another form for the image of the product. I tried adding this:
def anunciocreateview(request):
anuncio_form = AnuncioForm(request.POST or None)
producto_form = ProductoForm(request.POST or None)
imagen_form = ImagenForm(request.POST, request.FILES)
if request.method == "POST":
if all([anuncio_form.is_valid(), producto_form.is_valid(), imagen_form.is_valid()]):
anuncio = anuncio_form.save(commit=False)
anuncio.anunciante = request.user
anuncio.save()
producto = producto_form.save(commit=False)
producto.anuncio = anuncio
producto.save()
imagen = imagen_form.request.FILES.get('imagen')
if imagen:
Imagen.objects.create(producto=producto, imagen=imagen)
return HttpResponse(status=204, headers={'HX-Trigger' : 'eventsListChanged'})
else:
print(request.FILES)
else:
anuncio_form = AnuncioForm()
producto_form = ProductoForm()
imagen_form = ImagenForm()
context = {
'anuncio_form' : anuncio_form,
'producto_form' : producto_form,
'imagen_form' : imagen_form
}
return render(request, 'buyandsell/formulario.html', context)
But this happens:
1- The 'Image upload' form field shows error 'This field is required' at the moment of rendering the form.
2- If uploading an image and clicking submit, the redirect doesn't happen as the imagen_form is not marked as valid. No error pops in the console whatsoever (I'm handling requests with HTMX).
If I omit the 'request.FILES' when instantiating the form, the error when the form renders disappear, but it anyway doesn't upload the image nor the form.
What am I missing?
For reference, here is the HTML file:
<form class="row g-3" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Create new listing</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label for="{{ anuncio_form.titulo.auto_id }}">{{ anuncio_form.titulo.label }}</label>
{% render_field anuncio_form.titulo|add_error_class:"is-invalid" class="form-control" %}
</div>
<div class="mb-3">
<label for="{{ anuncio_form.envio.auto_id }}">{{ anuncio_form.envio.label }}</label>
{% translate "Select available delivery options" as input_place_holder %}
{% render_field anuncio_form.envio|add_error_class:"is-invalid" class="form-control" placeholder=input_place_holder %}
</div>
<h5>Product:</h5>
<div class="mb-3">
<label for="{{ producto_form.nombre.auto_id }}">{{ producto_form.nombre.label }}</label>
{% translate "Name of your product" as input_place_holder %}
{% render_field producto_form.nombre|add_error_class:"is-invalid" class=" form-control" placeholder=input_place_holder %}
</div>
<div class="mb-3">
<label for="{{ producto_form.descripcion.auto_id }}">{{ producto_form.descripcion.label }}</label>
{% translate "Give a detailed description of your product" as input_place_holder %}
{% render_field producto_form.descripcion|add_error_class:"is-invalid" class=" form-control" placeholder=input_place_holder %}
</div>
<div class="row g-3">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ producto_form.estado.auto_id }}">{{ producto_form.estado.label }}</label>
{% render_field producto_form.estado|add_error_class:"is-invalid" class=" form-control" %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ producto_form.cantidad.auto_id }}">{{ producto_form.cantidad.label }}</label>
{% render_field producto_form.cantidad|add_error_class:"is-invalid" class=" form-control" %}
</div>
</div>
</div>
<div class="row g-3">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ producto_form.precio_unitario.auto_id }}">{{ producto_form.precio_unitario.label }}</label>
{% render_field producto_form.precio_unitario|add_error_class:"is-invalid" class=" form-control" %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ producto_form.disponibilidad.auto_id }}">{{ producto_form.disponibilidad.label }}</label>
{% render_field producto_form.disponibilidad|add_error_class:"is-invalid" class=" form-control" %}
</div>
</div>
</div>
<h5>Images:</h5>
<div class="mb-3">
<label for="{{ imagen_form.imagen.auto_id }}">{{ imagen_form.imagen.label }}</label>
{% render_field imagen_form.imagen|add_error_class:"is-invalid" class=" form-control" %}
</div>
<div id="productforms"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-tertiary" hx-get="{% url 'buyandsell:create-product' %}" hx-target="#productforms" hx-swap="beforeend">Add new product</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary" hx-post="{% url 'buyandsell:createview' %}">Submit</button>
</div>
</div>
</form>
Edit:
forms.py for ImagenForm:
class ImagenForm(ModelForm):
class Meta:
model = Imagen
fields = ['imagen']
models.py for the Imagen model:
class Imagen(models.Model):
producto = models.ForeignKey(Producto, on_delete=models.CASCADE, related_name='imagen', blank=True, null=True)
imagen = models.ImageField(upload_to='marketplace/')
def __str__(self):
return f"Imagen de {self.producto}"
def save(self, *args, **kwargs):
self.image = resize_image(self.image, size=(350, 350))
super().save(*args, **kwargs)
Don't initialize forms with request.POST if it is not a POST request.
Two changes to fix your issue:
move first form init block under if request.method == "POST"
move else block one tab to the left so it becomes else to if request.method == "POST" instead of current version where it is else to if .is_valid()
if request.method == "POST":
anuncio_form = AnuncioForm(request.POST or None)
producto_form = ProductoForm(request.POST or None)
imagen_form = ImagenForm(request.POST, request.FILES)
if all([anuncio_form.is_valid(), producto_form.is_valid(), imagen_form.is_valid()]):
...
else:
anuncio_form = AnuncioForm()
producto_form = ProductoForm()
imagen_form = ImagenForm()
Now you use request.POST only on POST requests, instead you show empty forms. If a form is invalid on POST then it will be rendered with errors (if template is done cottectly) instead of showing empty forms back again.
For handling multiple forms with one view/template take a look at these answers: one two three
upd
For HTMX-requests it is also required to set hx-encoding="multipart/form-data" in form element attributes. Similar question HTMX docs
I'm not getting any option to select product list in order formenter image description hereModels.py
from django.db import models
from re import I
from django.utils import timezone
from django.dispatch import receiver
from more_itertools import quantify
from django.db.models import Sum
# Create your models here.
CHOICES = (
("1", "Available"),
("2", "Not Available")
)
class Brand(models.Model):
name = models.CharField(max_length=255)
status = models.CharField(max_length=10, choices=CHOICES)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=255)
status = models.CharField(max_length=10, choices=CHOICES)
def __str__(self):
return self.name
class Product(models.Model):
brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
code = models.CharField(max_length=10)
#image = models.ImageField(upload_to="media/product/images/")
quantity = models.IntegerField()
rate = models.FloatField(max_length=100)
status = models.CharField(max_length=10, choices=CHOICES)
def __str__(self):
return self.name
class Order(models.Model):
date = models.DateTimeField(auto_now_add=True)
sub_total = models.FloatField(max_length=100)
vat = models.FloatField(max_length=100)
total_amount = models.FloatField(max_length=100)
discount = models.FloatField(max_length=100)
grand_total = models.FloatField(max_length=100)
paid = models.FloatField(max_length=100)
due = models.FloatField(max_length=100)
payment_type = models.CharField(max_length=100)
payment_status = models.IntegerField()
status = models.IntegerField()
class OrderItem(models.Model):
order_id = models.ForeignKey(Order, on_delete=models.CASCADE)
product_id = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.IntegerField()
rate = models.FloatField(max_length=100)
total = models.FloatField(max_length=100)
status = models.IntegerField()
views.py
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.template.loader import render_to_string
from django.views.decorators.csrf import csrf_exempt
import json
from .models import Brand, Category, Product, Order, OrderItem
# Create your views here.
#login_required(login_url="/account/signin/")
def index(request):
return render(request, "index.html", {})
def signup(request):
if request.method == "POST":
if request.POST.get("pwd1") == request.POST.get("pwd2"):
print(request.POST.get("pwd1"))
user = User.objects.create(
username=request.POST.get("username")
)
user.set_password(request.POST.get("pwd1"))
user.save()
return redirect("/account/signin/")
else:
return redirect("/account/signup/")
return render(request, "signup.html", {})
def signin(request):
if request.method == "POST":
pass
user = authenticate(request, username=request.POST.get("username"), password=request.POST.get("password"))
if user:
login(request, user)
return redirect("/dashboard/")
else:
messages.error(request, "Username or password error!")
return redirect("/account/signin/")
return render(request, "login.html", {})
def logout_view(request):
logout(request)
return redirect("/account/signin/")
#login_required(login_url="/account/signin/")
def dashboard(request):
return render(request, "dashboard.html", {})
#csrf_exempt
#login_required(login_url="/account/signin/")
def products(request):
return render(request, "product.html", {})
#login_required(login_url="/account/signin/")
def categories(request):
return render(request, "categories.html", {})
def categories_list(request):
categories_lists = Category.objects.all()
html = render_to_string('modules/tables_categories.html', {"categories": categories_lists})
return JsonResponse({"message": "Ok", "html": html})
#csrf_exempt
def create_product(request):
data = dict()
if request.method == "GET":
categories_lists = Category.objects.all()
brands_lists = Brand.objects.all()
data['html'] = render_to_string('modules/add_product.html', {"categories": categories_lists, "brands": brands_lists})
else:
print(request.FILES)
Product.objects.create(
name=request.POST["name"],
brand=Brand.objects.get(id=request.POST["brand"]),
category=Category.objects.get(id=request.POST["category"]),
code=request.POST["code"],
quantity=request.POST["quantity"],
rate=request.POST["rate"],
status=request.POST["status"],
)
products_lists = Product.objects.all()
data['html'] = render_to_string('modules/tables_products.html', {"products": products_lists})
return JsonResponse(data)
#csrf_exempt
def products_list(request):
products_lists = Product.objects.all()
html = render_to_string('modules/tables_products.html', {"products": products_lists})
return JsonResponse({"message": "Ok", "html": html})
#login_required(login_url="/account/signin/")
def orders(request):
return render(request, "orders.html", {})
#login_required(login_url="/account/signin/")
def report(request):
return render(request, "report.html", {})
#csrf_exempt
def create_brand(request):
data = dict()
brand_name = request.POST.get("brandName")
brand_status = request.POST.get("brandStatus")
Brand.objects.create(name=brand_name, status=brand_status)
brands_list = Brand.objects.all()
data['html'] = render_to_string('modules/tables.html', {"brands": brands_list})
return JsonResponse(data)
#csrf_exempt
def create_categories(request):
data = dict()
category_name = request.POST.get("categoryName")
category_status = request.POST.get("categoryStatus")
Category.objects.create(name=category_name, status=category_status)
categories_lists = Category.objects.all()
data['html'] = render_to_string('modules/tables_categories.html', {"categories": categories_lists})
return JsonResponse(data)
#csrf_exempt
def remove_categories(request, id):
data = dict()
category = Category.objects.get(id=id)
category.delete()
categories_lists = Brand.objects.all()
data['html'] = render_to_string('modules/tables_categories.html', {"categories": categories_lists})
return JsonResponse(data)
#csrf_exempt
def edit_brand(request, id):
data = dict()
brand_name = Brand.objects.get(id=id)
if request.method == "GET":
data['html'] = render_to_string('modules/edit.html', {"brand": brand_name})
else:
brand_name.name = request.POST["brandName"]
brand_name.status = request.POST["brandStatus"]
brand_name.save()
brands_list = Brand.objects.all()
data['html'] = render_to_string('modules/tables.html', {"brands": brands_list})
return JsonResponse(data)
#csrf_exempt
def remove_brand(request, id):
data = dict()
brand = Brand.objects.get(id=id)
brand.delete()
brands_list = Brand.objects.all()
data['html'] = render_to_string('modules/tables.html', {"brands": brands_list})
return JsonResponse(data)
#login_required(login_url="/account/signin/")
def brand_list(request):
brands_list = Brand.objects.all()
html = render_to_string('modules/tables.html', {"brands": brands_list})
return JsonResponse({"message": "Ok", "html": html})
#csrf_exempt
#login_required(login_url="/account/signin/")
def brands(request):
return render(request, "brand.html", {})
#csrf_exempt
#login_required
def invoices(request):
invoice = Order.objects.all()
return render(request, 'report.html', {})
#login_required
def delete_invoice(request):
resp = {'status':'failed', 'msg':''}
if request.method == 'POST':
try:
invoice = Order.objects.get(id = request.POST['id'])
invoice.delete()
messages.success(request, 'Invoice has been deleted successfully')
resp['status'] = 'success'
except Exception as err:
resp['msg'] = 'Invoice has failed to delete'
print(err)
else:
resp['msg'] = 'Invoice has failed to delete'
return HttpResponse(json.dumps(resp), content_type="application/json")
order.html
If I select the product in this order form, the product list should appear. But the list does not appear.
{% extends 'modules/base.html' %}
{% load static %}
{% block content %}
<div class="container">
<div class="row vertical">
<div class="col-sm-12">
<div class="breadcrumb">
<p>Home / Orders </p>
</div>
<div class="card card-outline-secondary">
<div class="card-header">
<h3 class="mb-0 text-center">Manage Orders</h3>
</div>
<div class="card-block">
<form class="form form-horizontal" method="post" action="" id="createOrderForm">
<div class="form-group">
<label for="orderDate" class="col-sm-2 control-label">Order Date</label>
<div class="col-sm-12">
<input type="text" class="form-control" id="orderDate" name="orderDate"
autocomplete="off"/>
</div>
</div> <!--/form-group-->
<div class="form-group">
<label for="clientName" class="col-sm-2 control-label">Client Name</label>
<div class="col-sm-12">
<input type="text" class="form-control" id="clientName" name="clientName"
placeholder="Client Name" autocomplete="off"/>
</div>
</div> <!--/form-group-->
<div class="form-group">
<label for="clientContact" class="col-sm-2 control-label">Client Contact</label>
<div class="col-sm-12">
<input type="text" class="form-control" id="clientContact" name="clientContact"
placeholder="Contact Number" autocomplete="off"/>
</div>
</div>
<table class="table" id="productTable">
<thead>
<tr>
<th width="30%">Product</th>
<th width>Rate</th>
<th width="15%">Quantity</th>
<th width="20%">Total</th>
<th></th>
</tr>
</thead>
<tbody>
<tr id="" class="">
<td>
<div class="form-group">
<select class="form-control" name="productName[]"
id="productName<?php echo $x; ?>"
onchange="">
<option value="">SELECT</option>
</select>
</div>
</td>
<td>
<input type="text" name="rate[]" id="rate<?php echo $x; ?>"
autocomplete="off"
disabled="true" class="form-control"/>
<input type="hidden" name="rateValue[]" id="rateValue<?php echo $x; ?>"
autocomplete="off" class="form-control"/>
</td>
<td>
<div class="form-group">
<input type="number" name="quantity[]" id="quantity<?php echo $x; ?>"
onkeyup="" autocomplete="off"
class="form-control" min="1"/>
</div>
</td>
<td>
<input type="text" name="total[]" id="total<?php echo $x; ?>"
autocomplete="off"
class="form-control" disabled="true"/>
<input type="hidden" name="totalValue[]" id="totalValue<?php echo $x; ?>"
autocomplete="off" class="form-control"/>
</td>
<td>
<button class="btn btn-default removeProductRowBtn" type="button"
id="removeProductRowBtn" onclick="">
<i class="fa fa-trash" aria-hidden="true"></i></button>
</td>
</tr>
</tbody>
</table>
<div class="container">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="subTotal" class="col-sm-6 control-label">Sub Amount</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="subTotal" name="subTotal"
disabled="true"/>
<input type="hidden" class="form-control" id="subTotalValue"
name="subTotalValue"/>
</div>
</div> <!--/form-group-->
<div class="form-group">
<label for="vat" class="col-sm-6 control-label">VAT 13%</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="vat" name="vat"
disabled="true"/>
<input type="hidden" class="form-control" id="vatValue"
name="vatValue"/>
</div>
</div> <!--/form-group-->
<div class="form-group">
<label for="totalAmount" class="col-sm-6 control-label">Total Amount</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="totalAmount"
name="totalAmount" disabled="true"/>
<input type="hidden" class="form-control" id="totalAmountValue"
name="totalAmountValue"/>
</div>
</div> <!--/form-group-->
<div class="form-group">
<label for="discount" class="col-sm-6 control-label">Discount</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="discount" name="discount"
onkeyup="discountFunc()" autocomplete="off"/>
</div>
</div> <!--/form-group-->
<div class="form-group">
<label for="grandTotal" class="col-sm-6 control-label">Grand Total</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="grandTotal"
name="grandTotal" disabled="true"/>
<input type="hidden" class="form-control" id="grandTotalValue"
name="grandTotalValue"/>
</div>
</div> <!--/form-group-->
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="paid" class="col-sm-6 control-label">Paid Amount</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="paid" name="paid"
autocomplete="off" onkeyup="paidAmount()"/>
</div>
</div> <!--/form-group-->
<div class="form-group">
<label for="due" class="col-sm-6 control-label">Due Amount</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="due" name="due"
disabled="true"/>
<input type="hidden" class="form-control" id="dueValue"
name="dueValue"/>
</div>
</div> <!--/form-group-->
<div class="form-group">
<label for="clientContact" class="col-sm-6 control-label">Payment
Type</label>
<div class="col-sm-9">
<select class="form-control" name="paymentType" id="paymentType">
<option value="">SELECT</option>
<option value="1">Cheque</option>
<option value="2">Cash</option>
<option value="3">Credit Card</option>
</select>
</div>
</div> <!--/form-group-->
<div class="form-group">
<label for="clientContact" class="col-sm-6 control-label">Payment
Status</label>
<div class="col-sm-9">
<select class="form-control" name="paymentStatus" id="paymentStatus">
<option value="">SELECT</option>
<option value="1">Full Payment</option>
<option value="2">Advance Payment</option>
<option value="3">No Payment</option>
</select>
</div>
</div>
<div class="form-group submitButtonFooter" style="margin-top: 50px">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-default" onclick="addRow()"
id="addRowBtn" data-loading-text="Loading..."><i
class="glyphicon glyphicon-plus-sign"></i> Add Row
</button>
<button type="submit" id="createOrderBtn" data-loading-text="Loading..."
class="btn btn-success"><i
class="glyphicon glyphicon-ok-sign"></i> Save Changes
</button>
<button type="reset" class="btn btn-default" onclick="resetOrderForm()">
<i class="glyphicon glyphicon-erase"></i> Reset
</button>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<!--/card-block-->
</div>
</div>
</div>
</div>
{% endblock %}
{% block script %}
<script src="{% static 'js/order.js' %}"></script>
{% endblock %}
Not getting your quetion perfectly But you will get Idea By below code:
<select id="" class="" name="">
{% for i in Product %}
<option value="{{ i.name }}">
{{i.name }}
</option>
{% endfor %}
</select>
Basically you need to use jinja html and loop with the data/model(here Product) which is given from view.py(function) and then you can access each column of model(here name).
To do this you should create a serialiser and pass that as part of the context to the frontend and loop through that.
visit this link to see how t make a serializer docs
After you have created your serializer and lets say you named it ProductSerializer, you then add the below line to the place that passes data to that order page screen in the frontend. The below line serializes your raw queryset and passes it to your frontend to be consumable.
products = Product.objects.all()
products = ProductSerializer(cart, many=True)
context = {"products": products}
Then in your frontend you can access this and loop through like so:
<select id="" class="" name="">
{% for product in products %}
<option value="{{ product.name }}">
{{product.name }}
</option>
{% endfor %}
</select>
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.
This is my update view which I'm using to get pre-populated form. Although this is also not working.
def update(request, id):
item = get_object_or_404(BookEntry, id=id)
if request.method=="POST":
form = UpdateForm(request.POST, instance=item)
if form.is_valid():
post=form.save(commit=False)
post.save()
return HttpResponseRedirect(reverse('bms:index'), id)
else:
form=EntryForm(instance=item)
return HttpResponseRedirect(reverse('bms:index'), id)
return render(request, 'index.html', {'form':form})
This is my urls.py
url(r'^update/(?P<id>[0-9]+)/$', views.update, name='update'),
This is the error that I'm getting again and again:
NoReverseMatch at /bms/
Reverse for 'update' with arguments '('',)' not found. 1 pattern(s) tried: [u'bms/update/(?P[0-9]+)/$']
I'm not sure if passing the url in right way. This is what i'm doing:
<form action="{% url 'bms:update' book.id %}" id="updateform" name="updateform" method="POST">
When I look at traceback, it's showing something's wrong in above line and this line:
return render(request, "bms/index.html", context)
This is my index view:
def index(request):
context = {}
book_detail = BookEntry.objects.all()
context.update({
'book_detail': book_detail
})
response = {"status": False, "errors": []}
if request.is_ajax():
id = request.POST['id']
csrf_token = request.POST['csrfmiddlewaretoken']
response = {}
response['status'] = False
book = BookEntry.objects.filter(id=id).first()
context = {
"book": book,
"csrf_token": csrf_token
}
template = render_to_string("bms/index.html", context)
response['template'] = template
response['status'] = True
return HttpResponse(json.dumps(response), content_type="applicaton/json")
return render(request, "bms/index.html", context)
My index.html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Raleway">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.15.1/jquery.validate.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
function update_entry(id) {
var id = id
$.ajax({
url: "{% url 'bms:index' %}",
type: "POST",
data:{
'csrfmiddlewaretoken': '{{ csrf_token }}',
'id' : id,
},
success: function(response){
$("#updateform").modal("show");
}
});
}
function update_property(id) {
window.location.replace("/bms/update" + id+"/");
}
</script>
<style>
body{
font-family: Raleway;
}
</style>
</head>
<body>
<div class="container">
<div class="page-header">
<h1>Details of Books</h1>
</div>
<table class = "table table-bordered table-hover">
<tr>
<th>S No.:</th>
<th>Title:</th>
<th>Author:</th>
<th>Edition:</th>
<th>Publisher:</th>
<th>Genre:</th>
<th>Detail:</th>
<th>Language:</th>
<th>Price:</th>
<th>ISBN:</th>
<th>Action:</th>
</tr>
{% for item in book_detail %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ item.title }}</td>
<td>{{ item.author }}</td>
<td>{{ item.edition }}</td>
<td>{{ item.publisher }}</td>
<td>{{ item.genre }}</td>
<td>{{ item.detail }}</td>
<td>{{ item.language }}</td>
<td>{{ item.price }}</td>
<td>{{ item.isbn }}</td>
<td>
<a data-href="bms:update({{item.id}})" onclick="update_entry({{item.id}})" class="btn btn-warning" data-toggle="modal">
<span class = "glyphicon glyphicon-pencil"></span> Edit
</a>
</td>
</tr>
{% endfor %}
</table>
<div class="modal fade" id="updateform" role="dialog">
<div class="modal-dialog">
<div class = "modal-content">
<div class = "modal-header">
<button type = "button" class = "close" data-dismiss="modal">×</button>
<h3 class="modal-title">
<b>Update Details</b>
</h3>
</div>
<div class = "modal-body">
<form action="{% url 'bms:update' book.id %}" id="updateform" name="updateform" method="POST">
{% csrf_token%}
<div class = "form-group">
<label for = "title">
Title:
</label>
<input class = "form-control" id="book_title" type = "text" name="title" value="{{ book.title }}">
</div>
<div class="form-group">
<label for = "author">
Author:
</label>
<input id="book_author" class = 'form-control' type = "text" name="author" value="{{ book.author }}">
</div>
<div class = "form-group">
<label for = "edition">
Edition:
</label>
<input id="book_edition" type = "text" class = 'form-control' name="edition" value="{{ book.edition }}">
</div>
<div class = "form-group">
<label for ="publisher">
Publisher:
</label>
<input id="book_publisher" type = "text" name="publisher" class = 'form-control' value="{{ book.publisher }}"/>
</div>
<div class = "form-group">
<label for ="genre">
Genre:
</label>
<input id="book_genre" type = "text" name="genre" class = 'form-control' value="{{ book.genre }}"/>
</div>
<div class = "form-group">
<label for ="language">
Language:
</label>
<input id="book_language" type = "text" name="language" class = 'form-control' value="{{ book.language }}"/>
</div>
<div class = "form-group">
<label for ="price">
Price:
</label>
<input id="book_price" type = "text" name="price" class = 'form-control' value="{{ book.price }}"/>
</div>
<div class = "form-group">
<label for ="isbn">
ISBN:
</label>
<input id="book_isbn" type = "text" name="isbn" class = 'form-control' value="{{ book.isbn }}"/>
</div>
<input type = "submit" value="Update" id="update" class = "btn btn-success" style="font-size:18px;" />
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Does the BookEntry model have a primary key column? I started having the same error when I added a primary key field on the model the id was referencing. Apparently the id column is replaced by the primary key field. I removed the key and migrated the changes.The error is gone now.
For some reason I can't get my angular code to play nice with my python django application. When I submit the page it saves all null values in my db and my get response isn't working correctly either because nothing is returned. Any help will be greatly appreciated, I also included screen shots for a better picture of what I am trying to do.
angular code
var dim = angular.module('Dim', ['ngResource']);
dim.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
dim.factory("Dim", function ($resource) {
return $resource("/_dims.html/:id", { id: '#id' }, {
index: { method: 'GET', isArray: true, responseType: 'json' },
update: { method: 'PUT', responseType: 'json' }
});
})
dim.controller("DimController", function ($scope, $http, Dim) {
$scope.dims = Dim.index()
$scope.addDim = function () {
dim = Dim.save($scope.newDim)
$scope.dims.push(Dim)
$scope.newDim = {}
}
$scope.deleteDim = function (index) {
dim = $scope.dims[index]
Dim.delete(dim)
$scope.dims.splice(index, 1);
}
})
views.py
def add_dimensions(request):
if request.method == 'POST':
c_date = datetime.now()
u_date = datetime.now()
description = request.POST.get('description')
style = request.POST.get('style')
target = request.POST.get('target')
upper_limit = request.POST.get('upper_limit')
lower_limit = request.POST.get('lower_limit')
inspection_tool = request.POST.get('inspection_tool')
critical = request.POST.get('critical')
units = request.POST.get('units')
metric = request.POST.get('metric')
target_strings = request.POST.get('target_strings')
ref_dim_id = request.POST.get('ref_dim_id')
nested_number = request.POST.get('nested_number')
met_upper = request.POST.get('met_upper')
met_lower = request.POST.get('met_lower')
valc = request.POST.get('valc')
sheet_id = request.POST.get('sheet_id')
data = {}
dim = Dimension.objects.create(
description=description,
style=style,
target=target,
upper_limit=upper_limit,
lower_limit=lower_limit,
inspection_tool=inspection_tool,
critical=critical,
units=units,
metric=metric,
target_strings=target_strings,
ref_dim_id=ref_dim_id,
nested_number=nested_number,
met_upper=met_upper,
met_lower=met_lower,
valc=valc,
sheet_id=sheet_id,
created_at=c_date,
updated_at=u_date)
data['description'] = dim.description;
data['style'] = dim.style;
data['target'] = dim.target;
data['upper_limit'] = dim.upper_limit;
data['lower_limit'] = dim.lower_limit;
data['inspection_tool'] = dim.inspection_tool;
data['critical'] = dim.critical;
data['units'] = dim.units;
data['metric'] = dim.metric;
data['target_strings'] = dim.target_strings;
data['ref_dim_id'] = dim.ref_dim_id;
data['nested_number'] = dim.nested_number;
data['met_upper'] = dim.met_upper;
data['met_lower'] = dim.met_lower;
data['valc'] = dim.valc;
data['sheet_id'] = dim.sheet_id;
return HttpResponse(json.dumps(data), content_type="application/json",)
else:
return render(request, 'app/_dims.html')
url.py
urlpatterns = [
# Examples:
url(r'^$', app.views.home, name='home'),
url(r'^contact$', app.views.contact, name='contact'),
url(r'^about', app.views.about, name='about'),
#url(r'^sheet', app.views.sheet, name='sheet'),
url(r'^sheet/(?P<customer_id>\w+)$', app.views.sheet, name='sheet_customer'),
url(r'^sheet/sheet_form_create.html$', app.views.sheet_form_create, name='sheet_form_create'),
url(r'^sheet/sheet_form_create.html/get_work$', app.views.get_work, name='get_work'),
url(r'^sheet/(?P<pk>\d+)/sheet_update$', app.views.update_sheet, name='sheet_update'),
url(r'^_dims.html$', app.views.add_dimensions, name='dim_update'),
url(r'^sheet/(?P<pk>\d+)/delete_sheet$', app.views.delete_sheet, name='sheet_delete'),
url(r'^sheet/sheet_form_create.html/_dim$', app.views.add_dimensions, name='dim'),
url(r'^_dims.html(?P<pk>\d+)$', app.views.add_dimensions, name='dim'),
url(r'^$', app.views.dimtable_asJson, name='dim_table_url'),
#url(r^'grid_json/', include (djqgrid.urls)),
_dims.html
{% block content %}
<div class="container" ng-app="Dim">
<h1>Dimensions</h1>
<div ng-controller="DimController">
<div class="well">
<h3>Add Dimensions</h3>
<form ng-submit="addDim()">
<div class="row">
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.description" placeholder="Description" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.style" placeholder="Style" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.target" placeholder="Target" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.upper_limit" placeholder="Upper Limit" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.lower_limit" placeholder="Lower Limit" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.inspecton_tool" placeholder="Inspection Tool" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.critical" placeholder="Critical" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.units" placeholder="Units" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.metric" placeholder="Metric" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.target_strings" placeholder="Target Strings" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.ref_dim_id" placeholder="Ref Dim Id" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.nested_number" placeholder="Nested Number" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.met_upper" placeholder="Met Upper" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.met_lower" placeholder="Met Lower" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.valc" placeholder="Valc" type="text"></input>
</div>
<div class="col-xs-6">
<input class="form-control" ng-model="newDim.sheet_id" placeholder="Sheet ID" type="text"></input>
</div>
</div>
<div class="row">
<div class="col-xs-12 text-center">
<br/>
<input class="btn btn-primary" type="submit" value="Save Dimension">/</input> {% csrf_token %}
</div>
</div>
</form>
<table class="table table-bordered trace-table">
<thead>
<tr class="trace-table">
<th class="ts jp" style="border: solid black;">Description</th>
</tr>
</thead>
<tr class="trace-table">
<tr ng-repeat="dim in dims track by $index">
<td class="trace-table" style="border: solid black;">{{ dim.description }}</td>
</tr>
</tr>
</table>
</div>
</div>
</div>
<a class="btn btn-danger" ng-click="deleteDim($index)">_</a>
{% endblock %}.
As your network tab screenshot shows, you're sending JSON, not form-encoded data. So in Django you need to use json.loads(request.body) to get the data as a dict, rather than accessing request.POST which will always be empty.
Note that if you're doing something like this, you should almost certainly be using django-rest-framework, which allows you to define serializers and deserializers that will automatically convert your models to and from JSON, and additionally validate the submitted data.