I am working on a Django app where the user will be able to take any survey they pick from a list of surveys. For one of the surveys, they are supposed to select an image that best represents their mood. For their answer I do not need to record the image they selected, just the name of the mood it represents (for example, "cheerful"). Therefore, I have not yet added an "image" field to the model. However, the user should be able to see the image and select it. At the moment I am not able to display the images, only getting the names. I have checked my code and still unable to find the mistake. By the way, not getting any technical error messages. Any recommendations you have are appreciated. Below are my models, views, and HTML. I apologize for the lengthy files.
Thank you!
Models
User = settings.AUTH_USER_MODEL
class Questionnaire(models.Model):
name = models.CharField(max_length=255)
text = models.CharField(max_length=200)
def __str__(self):
return self.name
class Question(models.Model):
text = models.CharField(max_length=200)
questionnaire = models.ForeignKey(Questionnaire, on_delete=models.CASCADE, related_name='questions')
def __str__(self):
return self.text
class Answer(models.Model):
questionnaire = models.ForeignKey(Questionnaire, on_delete=models.CASCADE, related_name='answers', default='')
text = models.CharField(max_length=200)
def __str__(self):
return self.text
class Response(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
question = models.ForeignKey(Question, on_delete = models.CASCADE)
answer = models.ForeignKey(Answer, on_delete = models.CASCADE)
def __str__(self):
return '%s - %s - %s - %s' % (self.user, self.question, self.answer, self.date)
Views
from django.forms import ModelForm
class ResponseForm(ModelForm):
class Meta:
model = Response
fields = ['question', 'answer']
# widgets= {'answer': RadioSelect}
def __init__(self, *args, user=None, **kwargs):
self.user = user
super().__init__(*args, **kwargs)
def save(self, commit=True):
response = super().save(commit=False)
response.user = self.user
return response.save()
def take_questionnaire_fs(request, questionnaire_id):
ResponseFormSet = modelformset_factory(Response, form=ResponseForm, extra=0)
if request.method == 'POST':
formset = ResponseFormSet(request.POST or None, request.FILES, form_kwargs={'user': request.user})
if formset.is_valid():
print("Formset is valid")
formset.save()
return HttpResponseRedirect(reverse ('questionnaires:questionnaire_index'))
else:
print("Formset is NOT valid")
print(formset.errors)
print(formset.non_form_errors())
questions = Question.objects.filter(questionnaire_id=questionnaire_id)
answers = Answer.objects.filter(questionnaire_id=questionnaire_id)
return render(request, 'questionnaires/take_questionnaire_fs.html', {
'questions': questions,
'answers': answers,
})
HTML
{% extends "base.html" %}
{% block page_content %}
{% if questionnaire.name == 'Pick-a-Mood' %}
<form action="{{ request.url }}" method="post">
{% csrf_token %}
<style>
.circle-container {
position: relative;
width: 24em;
height: 24em;
padding: 2.8em;
/*2.8em = 2em*1.4 (2em = half the width of a link with img, 1.4 = sqrt(2))*/
/* border: dashed 1px; */
border-radius: 50%;
margin: 1.75em auto 0;
}
.circle-container label {
display: block;
position: absolute;
top: 50%; left: 50%;
width: 8em; height: 8em;
margin: -2em;
}
.circle-container img { display: block; width: 100%; }
.deg22_5 { transform: rotate(22.5deg) translate(12em) rotate(-22.5deg); }
.deg67_5 { transform: rotate(67.5deg) translate(12em) rotate(-67.5deg); }
.deg112_5 { transform: rotate(112.5deg) translate(12em) rotate(-112.5deg); }
.deg157_5 { transform: rotate(157.5deg) translate(12em) rotate(-157.5deg); }
.deg202_5 { transform: rotate(202.5deg) translate(12em) rotate(-202.5deg); }
.deg247_5 { transform: rotate(247.5deg) translate(12em) rotate(-247.5deg); }
.deg292_5 { transform: rotate(292.5deg) translate(12em) rotate(-292.5deg); }
.deg337_5 { transform: rotate(337.5deg) translate(12em) rotate(-337.5deg); }
/* HIDE RADIO */
[type=radio] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
/* IMAGE STYLES */
[type=radio] + img {
cursor: pointer;
}
/* CHECKED STYLES */
[type=radio]:checked + img {
border: 2px solid #f00;
}
[type=radio]:not(:checked) + img {
border: none;
}
</style>
<div class="circle-container">
<label class='center'>
<input type="radio" name="pickamood" value="Neutral">
<img src="/static/mysurveys/female_neutral.png">
</label>
<label class='deg22_5'>
<input type="radio" name="pickamood" value="Relaxed">
<img src="/static/mysurveys/female_relaxed.png">
</label>
<label class='deg67_5'>
<input type="radio" name="pickamood" value="Calm">
<img src="/static/mysurveys/female_calm.png">
</label>
<label class='deg112_5'>
<input type="radio" name="pickamood" value="Bored">
<img src="/static/mysurveys/female_bored.png">
</label>
<label class='deg157_5'>
<input type="radio" name="pickamood" value="Sad">
<img src="/static/mysurveys/female_sad.png">
</label>
<label class='deg202_5'>
<input type="radio" name="pickamood" value="Irritated">
<img src="/static/mysurveys/female_irritated.png">
</label>
<label class='deg247_5'>
<input type="radio" name="pickamood" value="Tense">
<img src="/static/mysurveys/female_tense.png">
</label>
<label class='deg292_5'>
<input type="radio" name="pickamood" value="Excited">
<img src="/static/mysurveys/female_excited.png">
</label>
<label class='deg337_5'>
<input type="radio" name="pickamood" value="Cheerful">
<img src="/static/mysurveys/female_cheerful.png">
</label>
</div>
<a>
<input type="submit" value="Submit" >
</a>
</form>
{% else %}
<form method="post" action="{{ request.url }}">
{% csrf_token %}
{% for question in questions %}
<h1>{{question.text}}</h1>
<label hidden="" for="id_form-{{ forloop.counter0 }}-question">Question:</label>
<select hidden="" name="form-{{ forloop.counter0 }}-question" id="id_form-{{ forloop.counter0 }}-question">
<option value="{{question.id}}" selected="">{{question.text}}</option>
</select>
<label for="id_form-{{ forloop.counter0 }}-answer">Answer:</label>
<select required="" name="form-{{ forloop.counter0 }}-answer" id="id_form-{{ forloop.counter0 }}-answer">
<option value="" selected="">---------</option>
{% for answer in answers %}
<option value="{{answer.id}}">{{answer.text}}</option>
{% endfor %}
</select>
<input type="hidden" name="form-{{ forloop.counter0 }}-id" value="{{ forloop.counter }}" id="id_form-{{ forloop.counter0 }}-id">
<input type="hidden" name="form-TOTAL_FORMS" value="{{questions|length}}" id="id_form-TOTAL_FORMS" />
<input type="hidden" name="form-INITIAL_FORMS" value="0" id="id_form-INITIAL_FORMS" />
<input type="hidden" name="form-MAX_NUM_FORMS" value="{{questions|length}}" id="id_form-MAX_NUM_FORMS" />
{% endfor %}
<br />
<br />
<input type="submit" value="Submit">
</form>
{% endif %}
{% endblock %}
You need to use static files.
Make sure it’s set up in your settings.py and then in the html load static and use it to get your files.
Eg. Assuming your files are in a static folder and that is set up in settings.py
<img src="{% static 'mysurveys/female_irritated.png' %}">
Try these steps in order:
Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.
In your settings file, define STATIC_URL:
STATIC_URL = '/static/'
In your template file
{% load static %}
<img src="{% static 'mysurveys/female_irritated.png' %}" alt="image alt">
Store your static files in a folder called static in your app. For example my_app/static/mysurveys/female_bored.png. As you done already
More informations in Django doc.
thank you for the suggestions! The static files were set up correctly, the error was that I needed to add the field 'questionnaire' to my views. The syntax is now:
def take_questionnaire_fs(request, questionnaire_id):
ResponseFormSet = modelformset_factory(Response, form=ResponseForm, extra=0)
if request.method == 'POST':
formset = ResponseFormSet(request.POST or None, request.FILES, form_kwargs={'user': request.user})
if formset.is_valid():
# do something with the formset.cleaned_data
print("Formset is valid")
formset.save()
return HttpResponseRedirect(reverse ('questionnaires:questionnaire_index'))
else:
print("Formset is NOT valid")
print(formset.errors)
print(formset.non_form_errors())
questionnaire = Questionnaire.objects.get(id=questionnaire_id)
questions = Question.objects.filter(questionnaire_id=questionnaire_id)
answers = Answer.objects.filter(questionnaire_id=questionnaire_id)
return render(request, 'questionnaires/questionnaire_lec.html', {
'questions': questions,
'answers': answers,
'questionnaire': questionnaire,
})
Related
This question already has answers here:
The view didn't return an HttpResponse object. It returned None instead
(7 answers)
Closed last month.
ValueError at /update_department/14
The view management.views.update_department didn't return an HttpResponse object. It returned None instead.Also when added with return statement data is not updating.
Request information
USER
admin
GET
No GET data
POST
Variable Value
csrfmiddlewaretoken
'XLqZBPhMKImvlfgWsNLeN1Ei8nz5u1HJ15IvAQV4JNwVMeG31rhDOD1q9PJuwXmz'
department_code
'15'
department_name_e
'Finance'
department_name_l
'Finance'
parent_code
''
submit
''
These are the details.I don't know why is there error here while all the posted data is right.also the form is not updating.
Models:
class Departments(models.Model):
department_code = models.CharField(db_column='Department_Code', primary_key= True, max_length=20, db_collation='SQL_Latin1_General_CP1_CI_AS') # Field name made lowercase.
department_name_e = models.CharField(db_column='Department_Name_E', max_length=50, db_collation='SQL_Latin1_General_CP1_CI_AS') # Field name made lowercase.
department_name_l = models.CharField(db_column='Department_Name_L', max_length=50, db_collation='SQL_Latin1_General_CP1_CI_AS') # Field name made lowercase.
parent_code = models.CharField(db_column='Parent_Code', max_length=20, db_collation='SQL_Latin1_General_CP1_CI_AS') # Field name made lowercase.
is_active = models.BooleanField(db_column='Is_Active') # Field name made lowercase.
created_by = models.IntegerField(db_column='Created_By') # Field name made lowercase.
created_date = models.DateTimeField(db_column='Created_date') # Field name made lowercase.
modified_by = models.IntegerField(db_column='Modified_By') # Field name made lowercase.
modified_date = models.DateTimeField(db_column='Modified_date') # Field name made lowercase.
class Meta:
db_table = 'Departments'
unique_together = (('department_code'),)
def __str__(self):
return str("self.department_name_e") or ''
View:
#login_required
def update_department(request, department_code):
dep_up = Departments.objects.get(department_code=department_code)
if request.method == "POST":
form = DepartmentsForm(request.POST, instance = dep_up)
if form.is_valid():
department_code = form.cleaned_data['department_code']
department_name_e = form.cleaned_data['department_name_e']
department_name_l = form.cleaned_data['department_name_l']
parent_code = form.cleaned_data['parent_code']
obj = form.save(commit = False)
obj.is_active = True
obj.created_by = request.user.id
obj.created_date = datetime.today()
obj.modified_by = request.user.id
obj.modified_date = datetime.today()
obj.save()
return HttpResponseRedirect('department_list')
forms:
class DepartmentsForm(forms.ModelForm):
class Meta:
model = Departments
fields = ['department_code','department_name_e','department_name_l','parent_code']
HTML:
{% extends 'base.html' %}
{% block title %}Update Company{% endblock title %}
{% block body %}
<div style="margin-left:22%" class=" top-marg">
<h2 ><strong>Company:</strong></h2><br><br>
<form class="" action="{%url 'update_company' comp_up.company_code %}" method="post">
{% csrf_token %}
<div style="margin-left:20%;margin-right:20%" class="form-floating ">
<input type="text" value="{{comp_up.company_code}}" class="form-control" id="company_code" name="company_code" placeholder="Company Code" required>
<label style="margin-left:15px" for="company_code">Company Code</label>
</div>
<br>
<div style="margin-left:20%;margin-right:20%" class="form-floating ">
<input type="text" value="{{comp_up.company_name_e}}" class="form-control" id = "company_name_e" name="company_name_e" placeholder="Enter Company" required>
<label style="margin-left:15px" for="company_name_e">Company Name English</label>
</div>
<br>
<div style="margin-left:20%;margin-right:20%" class="form-floating ">
<input type="text" value="{{comp_up.company_name_l}}" class="form-control" id = "company_name_l" name="company_name_l" placeholder="Enter Company" required>
<label style="margin-left:15px" for="company_name_e">Company Name Local</label>
</div>
<br>
<div style="margin-left:20%;margin-right:20%" class="form-floating ">
<input type="tel" value="{{comp_up.tel}}" class="form-control" id = "tel" name="tel" placeholder="Telephone Number" required>
<label style="margin-left:15px" for="tel">Telephone Number</label>
</div>
<br>
<div style="margin-left:20%;margin-right:20%" class="form-floating ">
<input type="tel" value="{{comp_up.fax}}" class="form-control" id = "fax" name="fax" placeholder="Enter Fax"required>
<label style="margin-left:15px" for="fax"> Fax Number</label>
</div>
<br>
<div style="margin-left:20%;margin-right:20%" class="form-floating ">
<textarea name="address" class="form-control" rows="4" cols="100" placeholder="Address" required>{{comp_up.address}}</textarea>
<label style="margin-left:15px" for="address">Address</label>
</div>
<br>
<div style="margin-left:20%;margin-right:20%" class="form-floating ">
<select class="form-control" name="country_id" required>
<option value="{{comp_up.country_id.id}}" >{{comp_up.country_id.country_name_e}}</option>
{% for con in country %}
<option value="{{con.id}}" >{{con.country_name_e}}</option>
{% endfor %}
</select>
</div>
<br>
<label style = "margin-left:21%; " for="logo">Logo</label>
<div class="form-floating" >
<input value="{{comp_up.}}" style = "margin-left:21%;" accept="image/*" type="file" name="logo" onchange="loadFile(event)" required> <br>
<img style = "margin-left:21%;" id="output" >
<script>
var loadFile = function(event) {
var output = document.getElementById('output');
output.src = URL.createObjectURL(event.target.files[0]);
output.onload = function() {
URL.revokeObjectURL(output.src) // free memory
}
};
</script>
</div>
<br><br>
<center>
<button type="submit" class="btn btn-success" name="submit">Update</button>
<button type="button" class="btn btn-primary" onclick="window.location.href = '{%url 'company_list'%}'" name="cancel">Cancel</button>
</center>
</form>
</div>
{% endblock body %}
You have provided HttpReponse only for POST and valid form. You should give the standard response (with empty form) for fresh entries or posting with errors. Like this:
#login_required
def update_department(request, department_code):
dep_up = Departments.objects.get(department_code=department_code)
if request.method == "POST":
form = DepartmentsForm(request.POST, instance = dep_up)
if form.is_valid():
...
return HttpResponseRedirect('department_list')
form = DepartmentsForm()
return render(request, 'template.html', context={'form': form})
let say these are the inputs of user, in my view it's well validated form.is_valid().
item code | description | unit | quantity
---------------------------------------------------------------
#itemInput1 | #descriptionInput1 | #unitInput1 | #quantityInput1
#itemInput2 | #descriptionInput2 | #unitInput2 | #quantityInput2
#itemInput3 | #descriptionInput3 | #unitInput3 | #quantityInput3
reqeust.POST.getlist('description')
return a list -> ['#descriptionInput1','#descriptionInput2','#descriptionInput3']
How can i save all the cells that the user enter to my MaterialIndent model??
just like in myview i could only save the last item only !!
# models
class MaterialIndent(models.Model):
material_indent_id = models.AutoField(primary_key=True)
date_request = models.DateTimeField(auto_now_add=True)
local_code = models.CharField(max_length=10, default='Local')
quotation = models.FileField(upload_to='files/', null=True, blank=True)
description = models.CharField(max_length=200)
unit = models.CharField(max_length=100)
quantity_requested = models.DecimalField(max_digits=12, decimal_places=2)
quantity_remained = models.DecimalField(max_digits=12, decimal_places=2, null=True)
request_for = models.CharField(max_length=50)
requester = models.ForeignKey(User, on_delete=models.CASCADE)
priority = models.CharField(max_length=100)
status = models.CharField(max_length=50, default='Store Checking')
def __str__(self):
return str(self.material_indent_id)
# form
class MaterialIndentForm(ModelForm):
class Meta:
model = MaterialIndent
fields = ['local_code', 'description', 'unit', 'quantity_requested', 'request_for', 'priority','quotation']
# views
def test(request):
available_stock = SparePartsStock.objects.filter(quantity__gte=0).values_list('local_code', flat=True)
if request.method == 'POST':
form = MaterialIndentForm(request.POST, request.FILES)
if form.is_valid():
length = len(request.POST.getlist('local_code'))
post = form.save(commit=False)
for r in range(length):
local_code = request.POST.getlist('local_code')[r]
description = request.POST.getlist('description')[r]
unit = request.POST.getlist('unit')[r]
quantity_requested = request.POST.getlist('quantity_requested')[r]
post.local_code = local_code
post.description = description
post.unit = unit
post.quantity_requested = quantity_requested
post.requester = request.user
post.quantity_remained = post.quantity_requested
post.status = 'Store Checking'
post.save()
print('form is valid')
else:
print(form.errors)
else:
sparestock = SparePartsStock.objects.all()
form = MaterialIndentForm()
context = {'form': form, 'stock':available_stock, 'table': sparestock}
return render(request, 'copy.html', {})
# template
{% extends 'inventory.html' %}
{% load static %}
{% load crispy_forms_filters %}
{% block title %}
SG
{% endblock %}
{% block head %}
<style>
.container{
padding: 100px;
}
#priority_label{
margin-left: 15px;
}
#submit_button {
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
background-color: #555555;/* Black */
}
.btn {
background-color: DodgerBlue;
border: none;
color: white;
padding: 12px 16px;
font-size: 16px;
cursor: pointer;
}
/* Darker background on mouse-over */
.btn:hover {
background-color: RoyalBlue;
}
#rowAdder{
margin-left: 15px;
right: 10px;
}
</style>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.1/dist/css/bootstrap.min.css">
<script src="{% static 'js/jQuery.js' %}"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.1/dist/js/bootstrap.bundle.min.js"></script>
{% endblock %}
{% block content %}
<div class="container">
<h2 style="">Material Indent</h2>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="card">
<div class="card-header">
<label id="priority_label" for="rate">Priority</label><br>
<div class="rate">
<input type="radio" id="star5" name="priority" value="High" required/>
<label for="star5" title="High">High</label>
<input type="radio" id="star4" name="priority" value="Medium" required/>
<label for="star4" title="Medium">Medium</label>
<input type="radio" id="star3" name="priority" value="Low" required/>
<label for="star3" title="Low">Low</label>
</div>
<input name="request_for" type="text" class="form-control m-input" placeholder="Requested For" required><br>
<label for="quotation">Quotation: </label>
<input type="file" name="quotation" placeholder="Quotation">
</div>
<div class="card-body">
<div class="">
<div class="col-lg-12">
<div id="row">
<div class="input-group m-3">
<div class="input-group-prepend">
<button class="btn btn-danger"
id="DeleteRow" type="button">
<i class="bi bi-trash"></i>
-
</button>
</div>
<input id="local_code0" name="local_code0" type="text" class="form-control m-input" placeholder="Local Code" required list="localList">
<datalist id="localList">
{% for item in stock %}
<option value={{ item }}>
{% endfor %}
</datalist>
<input name="description0" type="text" class="form-control m-input" placeholder="Description">
<input name="unit0" type="text" class="form-control m-input" placeholder="Unit">
<input name="quantity0" type="text" class="form-control m-input" placeholder="Quantity">
</div>
</div>
<div id="newinput"></div>
<button id="rowAdder" type="button"
class="btn btn-dark">
<span class="bi bi-plus-square-dotted" id="plus_sign">
</span> +
</button>
<input type="hidden" name="length" id="length">
</div>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="button button5" id="submit_button">Submit</button>
</div>
</form>
</div>
<script type="text/javascript" >
let count = Number(1)
document.getElementById('length').value = 0
console.log(document.getElementById('length').value)
$("#rowAdder").click(function () {
document.getElementById('length').value = count
newRowAdd =
'<div id="row"> <div class="input-group m-3">' +
'<div class="input-group-prepend">' +
'<button class="btn btn-danger" id="DeleteRow" type="button">' +
'<i class="bi bi-trash"></i> - </button> </div>' +
'<input name=local_code' + count +' type="text" class="form-control m-input" placeholder="Local Code" list="localList" required>'+
'<input name=description'+count+ ' type="text" class="form-control m-input" placeholder="Description" required>'+
'<input name=unit'+count+ ' type="text" class="form-control m-input" placeholder="Unit" required>'+
'<input name=quantity'+count+ ' type="text" class="form-control m-input" placeholder="Quantity" required> </div> </div>'
;
$('#newinput').append(newRowAdd);
count ++
});
$("body").on("click", "#DeleteRow", function () {
$(this).parents("#row").remove();
count --
})
</script>
<script src="{% static 'js/material_indent_autofill.js' %}"></script>
{% include 'spare_parts_table.html' %}
{% endblock %}
I'd like to create a dropdown select based in a first selected dropdown using Ajax/JQuery with Django
I alread make a couple of tests, but without success for now:
Models:
class MaintenanceEquipment(models.Model):
equip_id = models.CharField(max_length=30, auto_created=False, primary_key=True)
line_nm = models.CharField(max_length=20, blank=True, null = True)
sequence = models.CharField(max_length=30, blank=True, null = True)
equip_model = models.CharField(max_length=30, blank=True, null = True)
def __str__(self):
return self.equip_id
views:
from django.shortcuts import render
from maintenance.models import MaintenanceEquipment
def maintenanceIssueView(request):
equipment_list = MaintenanceEquipment.objects.all()
context = {'equipment_list':equipment_list}
return render(request, 'maintenance/maintenanceIssue.html', context)
def load_equipment(request):
if request.method == 'GET':
line = request.GET.get('line_nm')
equipment = MaintenanceEquipment.objects.filter(line_nm=line)
context = {'equipment': equipment}
return render(request, 'maintenance/maintenanceIssue.html', context)
maintenanceIssue.html:
<form method="POST" id="maintenanceForm" data-equipment-url="{% url 'ajax_load_equipment' %}" novalidate>
{% csrf_token %}
<div style="text-align:left;" class="container-fluid">
<div style="text-align:left;" class="form-row">
<div class="form-group col-md-6">
<label for="line_nm" style="font-size:medium;">Line</label>
<select class="form-control" id="line_nm" name="line_nm" >
{% for instance in equipment_list %}
<option id="{{ instance.line_nm }}" value="{{ instance.line_nm }}">{{ instance.line_nm }}</option>
{% endfor %}
</select>
</div>
<div class="form-group col-md-6">
<label for="equip_sequence" style="font-size:medium;">Machine</label>
<select class="form-control" id="equip_sequence" name="equip_sequence">
{% for instance in equipment %}
<option id="{{ instance.equip_id }}" value="{{ instance.sequence }}">{{ instance.sequence }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</form>
<script>
$("#line_nm").change(function () {
var url = $("#maintenanceForm").attr("data-equipment-url");
var lineID = $(this).val();
$.ajax({
url: url,
data: {
'line_nm': lineID
},
success: function (data) {
$("#equip_sequence").html(data);
}
});
});
</script>
As result, the line_nm has been called by ajax into my load_equipment view, but is not returning to the second select dropdown: equip_sequence, it appears empty
What is your response in console if you make:
success: function(data){
alert(data);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Status: " + textStatus); alert("Error: " + errorThrown);
}
Do you get any error messages in your logfiles?
** urls.py file **
from django.urls import path
from main import views
app_name = 'main'
urlpatterns = [
path('', views.home, name='home'),
path('submit/', views.submit, name='submit'),
path('error-log/', views.error_log, name='error_log'),
]
** views.py file **
from django.shortcuts import render, get_object_or_404, redirect
import socket
from main.models import Paragraphs, Store_user_para
from main.forms import Store_user_para_forms
import random
global paragraph
def home(request):
''' to get the ip of user'''
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
'''code to pass the pre defined paragraphs to the user '''
paragraphs = Paragraphs.objects.filter(active=True)
''' code to generate random paragraph '''
len_paragraphs = len(paragraphs)
number = random.randint(1, len_paragraphs-1)
paragraph = get_object_or_404(Paragraphs, id=number)
form = Store_user_para_forms()
return render(request, 'main/home.html', {'ip_address':ip_address, 'paragraph':paragraph, 'form':form})
def submit(request):
if request.method == "POST":
try:
global paragraph
form = Store_user_para_forms(request.POST)
data = form.save(commit=False)
data.paragraph_Id = request.POST.get('hidden_value', '')
data.user = request.user
data.save()
return redirect('main:submit')
except (ValueError):
form = Store_user_para_forms(request.POST)
print(form)
return render(request, 'main/submit.html', {'error':'Bad data passed in. Try again.'})
else:
data = Store_user_para.objects.filter()
return render(request, 'main/submit.html', {'data':data})
def error_log(request ):
return render(request, 'main/error_log.html')
** model.py file **
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Paragraphs(models.Model):
''' this class will store the pre defined paragraphs in backend '''
objects = models.Manager()
paragraph = models.TextField(blank=False, null=False)
created = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
class Meta:
verbose_name = 'Paragraph'
verbose_name_plural = 'Paragraphs'
def __str__(self):
return self.paragraph.split()[0]+ ' ' + self.paragraph.split()[1] + '...'
class Store_user_para(models.Model):
''' this class will store the users entered paragraph '''
objects = models.Manager()
paragraph_Id = models.ForeignKey('Paragraphs', on_delete=models.SET_NULL, null=True)
user_paragraph = models.TextField(null=False, blank=False)
user = models.ForeignKey(User, on_delete=models.CASCADE)
submitted = models.DateTimeField(auto_now_add=True)
Errors = models.IntegerField(null=True)
def __str__(self):
return self.user.username
** form.py file **
from django import forms
from main.models import Store_user_para
class Store_user_para_forms(forms.ModelForm):
class Meta:
model = Store_user_para
''' field to display on form '''
fields = [ 'user_paragraph']
** Home.html file , when I hit the submit button, I want not only to pass the user written pargraph but also the stored paragraph id to the store_user_para model **
{% extends 'main/base.html' %}
{% load static %}
{% block title %} | Home | {% endblock %}
{% block content %}
<form action="{% url 'main:submit' %}" method="POST">
{% csrf_token %}
<div class="unselectable" style="margin: 50px; margin-bottom: 20px;">
<div style="border: .1em solid green;">
<div style="font-size:20px; padding: 20px;">
<!-- this will bring the paragraphs from backend -->
{{ paragraph.paragraph }}
<input type="hidden" name='hidden_value' value="{{ paragraph.paragraph }}" >
</div>
</div>
</div>
<div style="margin: 50px; margin-top:15px ;">
<label for="id_user_paragraph"> </label>
<textarea name="user_paragraph" cols="40" rows="12" required="" id="id_user_paragraph"
placeholder="Start writing here" style="width: 100%; height:300px; font-size: 20px; padding: 5px; border: solid green 1px; "></textarea>
<button id="submit" type="submit" style="display: none;">Complete</button>
</div>
</form>
<div class="text-center">
<p class="btn btn-info disabled">Your IP: {{ ip_address }}</p>
</div>
<div class="row">
<div class="col-12 col-md-6 col-lg-6 col-sm-6 ">
<form action="">
<div class="text-right">
<button type="button" style="-ms-text-underline-position: none;" class="btn btn-outline-success" onclick="$('#submit').click()">
submit and check
</button>
</div>
</form>
</div>
<div class="col-12 col-md-6 col-lg-6 col-sm-6 ">
<div class="text-left">
<a href="{% url 'main:error_log' %}" style="-ms-text-underline-position: none;" class="btn btn-outline-danger mr-3">
view error log
</a>
</div>
</div>
</div>
<div style="margin-left: 10px; margin-top: 10px;">
<h4>work and payment details </h4>
</div>
<div style="margin-top: 10px; margin-left: 10px; margin-bottom: 50px;">
<h6>Target : n Paragraphs</h6>
<h6>Time : 00:00 - 00:00 </h6>
</div>
{% endblock %}
** this is the output in backend **
image of admin site
**how to submit the pre defined pargraph here **
you need to add the id to the fields list in forms.py
fields = ('id', 'user_paragraph')
then you can return it the same way as the paragraph
I have implemented a Dependent dropdown list within Django but when I try to submit the form I get the following error 'Select a valid choice. That choice is not one of the available choices.'
I have spent a while looking on the web for the answer and have tried a few with little avail.
From my understanding and reading, this is an error because I render the form with a queryset of none. Then I use ajax to fill in the options. Even though I have updated the dropdown list, the form validation is checking my submitted answer against a queryset of none - thus the error.
So i'm hoping someone can help me to update the choices the form will accepted on form submission.
views.py
# stage6 is where I render my view and check validation
def stage6(request):
form_deal = DealForm(request.POST or None, prefix='inst')
if form_deal.is_valid():
form_deal.save()
messages.success(request, 'Deal added successfully.')
form_deal = DealForm()
context = {
'dform': form_deal,
}
return render(request, 'stages/stage6/stage6.html', context)
# This is used for my ajax request
def load_offers(request):
property_process_id = request.GET.get('propertyprocess_link')
offers = Offer.objects.filter(propertyprocess_link=property_process_id).order_by('id')
return render(request, 'stages/stage6/offers_dropdown_list.html', {'offers': offers})
forms.py
class DealForm(forms.ModelForm):
deal_date = forms.CharField(
label='',
widget=forms.TextInput(attrs={'type': 'date'})
)
target_move_date = forms.CharField(
label='',
widget=forms.TextInput(attrs={'type': 'date'})
)
def __init__(self, *args, **kwargs):
super(DealForm, self).__init__(*args, **kwargs)
# filter the foreign keys shown
self.fields['propertyprocess_link'].queryset = PropertyProcess.objects.filter(sector="Sales")
# filter used for ajax request
self.fields['offer_accepted'].queryset = Offer.objects.none()
# add a "form-control" class to each form input
# for enabling bootstrap
for name in self.fields.keys():
self.fields[name].widget.attrs.update({
'class': 'form-control',
})
class Meta:
model = Deal
fields = ('propertyprocess_link',
'deal_date',
'price_agreed',
'target_move_date',
'offer_accepted'
)
models.py
class Deal(models.Model):
propertyprocess_link = models.ForeignKey(PropertyProcess,
on_delete=models.CASCADE)
deal_date = models.DateField()
price_agreed = models.IntegerField()
target_move_date = models.DateField()
offer_accepted = models.ForeignKey(Offer,
on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "deals"
def __str__(self):
return '%s, %s' % (
self.propertyprocess_link.property_link.address_line_1,
self.propertyprocess_link.property_link.postcode
)
html
{% block content %}
<div class="container-fluid header-container">
<div class="row">
<div class="col-sm-9 col-md-7 col-lg-5 mx-auto">
<div class="card-au card-signin my-5">
<div class="card-body">
<form id="offers-form" data-offers-url="{% url 'ajax_load_offers' %}" class=" text-center text-white" method="post" novalidate>
{% csrf_token %}
{{ dform.non_field_errors }}
<div class="form-colour mt-2">
{{ dform.propertyprocess_link.errors }}
<label class="mb-0 mt-1">Property Being Offered On:</label>
{{ dform.propertyprocess_link }}
</div><div class="form-colour mt-2">
{{ dform.offer_accepted.errors }}
<label class="mb-0 mt-1">Offer Being Accepted:</label>
{{ dform.offer_accepted }}
</div>
<div class="form-colour mt-2">
{{ dform.price_agreed.errors }}
<label class="mb-0 mt-1">Price Agreed:</label>
{{ dform.price_agreed }}
</div>
<div class="form-colour mt-2">
{{ dform.deal_date.errors }}
<label class="mb-0 mt-1">Deal Date:</label>
{{ dform.deal_date }}
</div>
<div class="form-colour mt-2">
{{ dform.target_move_date.errors }}
<label class="mb-0 mt-1">Target Move Date:</label>
{{ dform.target_move_date }}
</div>
<div class="mb-3"></div>
{# hidden submit button to enable [enter] key #}
<div class="hidden-btn" style="margin-left: -9999px"><input class="hidden-btn" type="submit" value=""/></div>
<div class="text-center mt-2">
<input type="submit" class="login-btn btn-green btn btn-lg border-green text-uppercase py-3" value="Add Deal" />
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block postloadjs %}
{{ block.super }}
<script>
$("#id_inst-propertyprocess_link").change(function () {
var url = $("#offers-form").attr("data-offers-url"); // get the url of the `load_offers` view
var propertyID = $(this).val(); // get the selected Property Process ID from the HTML input
$.ajax({ // initialize an AJAX request
url: url, // set the url of the request (= localhost:8000/ajax/load-offers/)
data: {
'propertyprocess_link': propertyID // add the Property Process id to the GET parameters
},
success: function (data) { // `data` is the return of the `load-offers` view function
$("#id_inst-offer_accepted").html(data); // replace the contents of the offers input with the data that came from the server
}
});
});
</script>
{% endblock postloadjs %}
Thanks very much for any help anyone can give.