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.
Related
I am working on a feature that allow to update the properties of a node (name etc.). So in my changeservice.html I first populate a list with all nodes. Then depending on the selection an AJAX function is fetching all node details and pre-populates a form. Now everything works fine, I can change the values of all fields but one input in particular - service_name . Then for some reason all other fields disappear from the screen and are not even submitted with the POST afterwards, resulting in the following error:
File "C:\Users\nb67ab\Envs\virtualobeya4dec\virtualobeya\views.py", line 437, in changeservice features_1 = request.form['features_1']
File
"C:\Users\nb67ab\Envs\virtualobeya4dec\Lib\site-packages\werkzeug\datastructures.py",
line 443, in getitem raise exceptions.BadRequestKeyError(key)
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser
(or proxy) sent a request that this server could not understand.
KeyError: 'features_1'
My HTML looks like:
{% extends "layouts/layout.html" %}
{% block content %}
<div class="main-content">
<!-- Basic Form area Start -->
<div class="container-fluid">
<!-- Form row -->
<div class="row">
<div class="col-lg-12 ">
<div class="card">
<div class="card-body">
<h4 class="card-title">Change Service</h4>
<div class="form-row">
<div class="form-group col-md-4">
<label for="service_selected" class="col-form-label">Select Service or PB</label>
<select id="service_selected" name="platform_selected" class="form-control">
<option>Choose</option>
{% for x in services %}
<option value="{{x.name}},{{ x.type }},{{ x.pname }}">{{ x.name }},{{ x.type }},{{ x.pname }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</div>
<div class="card" id="service_details" style="display: none">
<div class="card-body">
<form action="{{ url_for('changeservice') }}" method="post">
<div class="form-row">
<div id="service_name_old" class="form-group col-md-4" style="display: none">
<label for="servicenameold" class="col-form-label">Service Name Old</label>
<input type="text" class="form-control" name="servicenameold" id="servicenameold" placeholder="">
<label for="domainnameold" class="col-form-label">Domain Name Old</label>
<input type="text" class="form-control" name="domainnameold" id="domainnameold" placeholder="">
<label for="platformnameold" class="col-form-label">Platform Name Old</label>
<input type="text" class="form-control" name="platformnameold" id="platformnameold" placeholder="">
</div>
<div class="form-group col-md-3">
<div class="custom-control custom-radio">
<input type="radio" id="EPS" name="type" class="custom-control-input" value="EPS" checked>
<label class="custom-control-label" for="EPS">Exposed Platform Service</label>
</div>
</div>
<div class="form-group col-md-3">
<div class="custom-control custom-radio">
<input type="radio" id="ESPB" name="type" class="custom-control-input" value="ESPB">
<label class="custom-control-label" for="ESPB">Exposed Supplied Product Build</label>
</div>
</div>
<div class="form-group col-md-3">
<div class="custom-control custom-radio">
<input type="radio" id="ETES" name="type" class="custom-control-input" value="ETES">
<label class="custom-control-label" for="ETES">Exposed Tied Engineering Support</label>
</div>
</div>
<div class="form-group col-md-3">
<div class="custom-control custom-radio">
<input type="radio" id="ET" name="type" class="custom-control-input" value="ET">
<label class="custom-control-label" for="ET">Exposed Training&Counseling</label>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="selected_domain" class="col-form-label">Select domain where service belongs</label>
<select id="selected_domain" name="selected_domain" class="form-control">
<option>Choose</option>
{%for x in domain%}
<option value="{{x}}">{{x}}</option>
{%endfor%}
</select>
</div>
<div class="form-group col-md-6">
<label for="selected_platform" class="col-form-label">Select platform exposing the service</label>
<select name="selected_platform" id="selected_platform" class="form-control">
<option>Choose</option>
{%for x in platform%}
<option value="{{x}}">{{x}}</option>
{%endfor%}
</select>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label class="col-form-label">Service Name</label>
<input type="text" class="form-control" name="service_name" id="service_name" placeholder="Service Name">
</div>
</div>
<div class="form-row">
<div id="features" class="form-group col-md-3">
</div>
<div id="options" class="form-group col-md-3">
</div>
<div id="qualities" class="form-group col-md-3">
</div>
<div id="aspects" class="form-group col-md-3">
</div>
</div>
<div>
<button type="submit" class="btn btn-primary">Change Service</button>
</div>
<div class="message-box">
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/ajax.js') }}"></script>
{% endblock %}
The Ajax Script looks like:
$("#service_selected").on('change', function(){
$.ajax(
{
url: '/returnservicedetails',
data:{
serviceselect: $("#service_selected").val()
},
success: function (data,status,xhr) { // success callback function
if (data.length > 0){
var js = JSON.parse(data);
console.log(data);
var servicename = js[0]['name'];
var type = js[0]['type'];
var domain=js[0]['dname'];
var platform=js[0]['pname'];
var features=js[0]['features'];
var serviceoptions = js[0]['options'];
var qualities=js[0]['qualities'];
var aspects = js[0]['aspects'];
$('#servicenameold').val(servicename);
$('#service_name').val(servicename);
if (type=='EPS') {
$('#EPS').prop('checked',true);
$(':radio:not(:checked)').attr('disabled', true);
}
else {
if (type=='ESPB') {
$('#ESPB').prop('checked',true);
$(':radio:not(:checked)').attr('disabled', true);
}
else {
if (type=='ETES') {
$('#ETES').prop('checked',true)
$(':radio:not(:checked)').attr('disabled', true);
}
else {
$('#ET').prop('checked',true)
$(':radio:not(:checked)').attr('disabled', true);
}
}
}
$('#selected_domain').val(domain);
$('#domainnameold').val(domain);
$('#selected_platform').val(platform);
$('#platformnameold').val(platform)
var features1 = '<label class="col-form-label">Features</label>';
for (var j = 0; j < features.length; j++) {
features1 += '<input type="text" class="form-control" name="features_' + (j + 1) + '" id="features_' + (j + 1) + '" placeholder="" value="' + features[j]+'" >';
}
$("#features").empty('').append(features1);
var serviceoptions1 = '<label class="col-form-label">Options</label>';
for (var j = 0; j < serviceoptions.length; j++) {
serviceoptions1 += '<input type="text" class="form-control" name="options_' + (j + 1) + '" id="options_' + (j + 1) + '" placeholder="" value="' + serviceoptions[j]+'" >';
}
$("#options").empty('').append(serviceoptions1);
var qualities1 = '<label class="col-form-label">Qualities</label>';
for (var j = 0; j < qualities.length; j++) {
qualities1 += '<input type="text" class="form-control" name="qualities_' + (j + 1) + '" id="qualities_' + (j + 1) + '" placeholder="" value="' + qualities[j]+'" >';
}
$("#qualities").empty('').append(qualities1);
var aspects1 = '<label class="col-form-label">Aspects</label>';
for (var j = 0; j < aspects.length; j++) {
aspects1 += '<input type="text" class="form-control" name="aspects_' + (j + 1) + '" id="aspects_' + (j + 1) + '" placeholder="" value="' + aspects[j]+'" >';
}
$("#aspects").empty('').append(aspects1);
$("#service_details").show()
}
else {
$("#service_details").hide()
}
},
error: function (jqXhr, textStatus, errorMessage) { // error callback
}
});
})
The Python endpoint looks like:
#app.route('/changeservice', methods=["GET","POST"])
def changeservice():
user=User(session["username"])
if request.method=="POST":
servicenameold=request.form['servicenameold']
domainnameold=request.form['domainnameold']
platformnameold=request.form['platformnameold']
newservicename=request.form['service_name']
domainnamenew=request.form['selected_domain']
platformnamenew=request.form['selected_platform']
stype=request.form['type']
features_1 = request.form['features_1']
features_2 = request.form['features_2']
features_3 = request.form['features_3']
features_4 = request.form['features_4']
options_1 = request.form['options_1']
options_2 = request.form['options_2']
options_3 = request.form['options_3']
options_4 = request.form['options_4']
qualities_1 = request.form['qualities_1']
qualities_2 = request.form['qualities_2']
qualities_3 = request.form['qualities_3']
qualities_4 = request.form['qualities_4']
aspects_1 = request.form['aspects_1']
aspects_2 = request.form['aspects_2']
aspects_3 = request.form['aspects_3']
aspects_4 = request.form['aspects_4']
features_all = [features_1, features_2, features_3, features_4]
options_all = [options_1, options_2, options_3, options_4]
qualities_all = [qualities_1, qualities_2, qualities_3, qualities_4]
aspects_all = [aspects_1, aspects_2, aspects_3, aspects_4]
if not newservicename or not domainnamenew or not platformnamenew:
flash("You must specify Service Name, Domain and Platform")
else:
nodeid=Services.returnexposedID(servicenameold,stype,platformnameold)
servicedetails=Services.returnExposedDetails(nodeid)
if servicedetails[0]['name']==newservicename and servicedetails[0]['features']==features_all and servicedetails[0]['options']==options_all and servicedetails[0]['qualities']==qualities_all and servicedetails[0]['aspects']==aspects_all and servicedetails[0]['dname']==domainnamenew and servicedetails[0]['pname']==platformnamenew:
flash("No changes were made")
else:
user.unhookServiceFromPandD(nodeid)
user.updateExposedProperties(nodeid,newservicename,domainnamenew,platformnamenew,features_all,options_all,qualities_all,aspects_all)
user.updateExposedsurroundings(nodeid)
platforms = Platforms.listAllplatforms()
domains = Domains.listdomains()
services=Services.listallexposed()
return render_template("changeservice.html",services=services,platform=platforms,domain=domains)
I forgot that all variables in Javascript are global, I had another function listening on a field with the same name.
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.
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>
my files in project is:
djangoTry
--views.py
--forms.py
--others not included in this question files
When I click submit in my form I call this method from views.py:
from .forms import NameForm
def kontakt(request):
if request.method == 'POST':
form = NameForm(request.POST)
form.test("test")
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
phone_number = form.cleaned_data['phone_number']
email = form.cleaned_data['email']
details = form.cleaned_data['details']
return HttpResponseRedirect('/')
else:
form = NameForm()
return render(request, 'index.html', {'form':form})
NameForm is class from forms.py file:
from django import forms
class NameForm(forms.Form):
first_name = forms.CharField(label='first_name', max_length=100)
last_name = forms.CharField(label='last_name', max_length=100)
phone_number = forms.CharField(label='phone_number', max_length=100)
email = forms.CharField(label='email', max_length=100)
details = forms.CharField(label='details', max_length=100)
def test(self, message):
print("i'm in test and message is: %s " , (message))
print(self.first_name)
def is_valid(self):
print("jest valid")
return True
form.html
<form class="col s12" action="{% url 'kontakt' %}" method="post">
{% csrf_token %}
{{ form }}
<div class="row">
<div class="input-field col s6">
<input
id="first_name"
type="text"
value="hehe">
<!-- value="{{ form.first_name }}"> -->
<label for="first_name">First name</label>
</div>
<div class="input-field col s6">
<input
id="last_name"
type="text"
autocomplete="off"
value="hehe">
<!-- value="{{ form.last_name }}" > -->
<label for="last_name">Last name</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input id="phone_number" type="number" autocomplete="off"
value="123456789">
<label for="phone_number">Phone number</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input id="email" type="email" autocomplete="off" value="rafald121#gmail.com" >
<label for="email">Email</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input id="details" type="text" autocomplete="off" value="qweqweqeq">
<label for="details">Details</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<a class="waves-effect waves-light btn">
<input id="submit" type="submit" >
<i class="material-icons right">send</i>
</a>
<!-- <input id="submit" type="submit" > -->
<label for="details">Details</label>
</div>
</div>
</form>
but everytime I get error:
AttributeError: 'NameForm' object has no attribute 'first_name'
but NameForm has "first_name" atribute
NameForm's method "test" work properly everytime but any of NameForm's variable can't be called.
Does anybody have idea what's going on ?
I can't get my angular code to work with get or post responses any help would be greatly appreciated. I have included screen shots to give a better idea of what I am dealing with.
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.datetime.now()
u_date = datetime.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:
#dim_form = DimForm()
c_date = datetime.datetime.now()
dim_data = Dimension.objects.filter(created_at__lte=c_date)
#dim_serial = json.dumps(dim_data, cls = MyEncoder)
return HttpResponse(json.dumps(dim_data, cls=MyEncoder))
#return render(request, 'app/_dims.html', {'dim_form': dim_form})
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return int(mktime(obj.timetuple()))
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 %}.
screen shots
GET RESPONSE NOT LOADING DATA
POST RESPONSE SAVING ALL NULL VALUES TO MY DB
NOT A CSFR ISSUE