I'm having an issue with Django while updating inline formsets. I want to update a form and an inline formset, but it raises this error:
"MultiValueDictKeyError"
Exception Value: "u'clientphone_set-0-id'"
This is my view:
def edit_client(request, client_id):
client_to_edit = Client.objects.get(id=client_id)
form = ClientForm(instance=client_to_edit)
phone_formset = ClientPhoneFormSet(instance=client_to_edit)
if request.method == 'POST':
form = ClientForm(request.POST, instance=client_to_edit)
if form.is_valid():
form_saved = form.save(commit=False)
phone_formset = ClientPhoneFormSet(request.POST, request.FILES, instance=form_saved)
if phone_formset.is_valid():
form_saved.save()
phone_formset.save()
return client(request)
return render(request, 'WorkOrders/add_client.html', {'form' : form, 'phone_formset' : phone_formset})
And these are my forms
class ClientForm(forms.ModelForm):
name = forms.CharField(max_length=128)
rif = forms.CharField(max_length=10)
address = forms.CharField(max_length=250)
class Meta:
model = Client
fields = ('name','rif','address',)
ClientPhoneFormSet = inlineformset_factory(Client, ClientPhone, extra=1, fields=('phone_number',), can_delete=True)
And this is my template
<form class="form-horizontal" id="add_client" method="post" action=".">
{% csrf_token %}
{% for field in form.visible_fields %}
<div class="form-group">
<label for="{{ field.id }}" class="col-sm-2 control-label">{{ field.help_text }}</label>
<div class="col-sm-10">
{{ field.errors }}
{{ field }}
</div>
</div>
{% endfor %}
<div class="form-group">
<label for="{{ field.id }}" class="col-sm-2 control-label">Teléfono</label>
<div class="col-sm-10">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
{% for form in phone_formset.forms %}
<tr>
<td>
{% if form.instance.pk %}
{{ form.DELETE }}
{% endif %}
{{ form.errors }}
{{ form.phone_number }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{{ phone_formset.management_form }}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">Guardar</button>
Volver
</div>
</div>
</div>
</form>
It opens the form with no problem, the error happens when I submit.
Thanks.
I fixed it by using phone_formset instead of phone_formset.forms, and added the {{ phone_field.id }}.
Here is the result:
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
{% for phone_field in phone_formset %}
<tr>
<td>
{% if phone_field.instance.pk %}
{{ phone_field.DELETE }}
{% endif %}
{{ phone_field.errors }}
{{ phone_field.id }}
{{ phone_field.phone_number }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
Related
UPDATE(enter image description here I have added backslash to the url and new error comes out )
My idea is to have Teachers and Students and I want my Teachers to have the ability to edit quizzes for the students for some reason when I try to acces the QuizUpdateView via other ListView it gives me 404 Not Found screenshot
So I want to edit my quiz with this view:
class QuizUpdateView(views.UpdateView):
model = Quiz
fields = ('name', 'subject', )
context_object_name = 'quiz'
template_name = 'classroom/quiz_update.html'
def get_context_data(self, **kwargs):
kwargs['questions'] =
self.get_object().questions.annotate(answers_count=Count('answers'))
return super().get_context_data(**kwargs)
def get_queryset(self):
return self.request.user.quizzes.all()
def get_success_url(self):
return reverse_lazy('quizzes')
I have int:pk in my urls.py
urlpatterns = (
path('register', RegisterView.as_view(), name='register'),
path('register/student', StudentRegisterView.as_view(), name='register student'),
path('register/register', TeacherRegisterView.as_view(), name='register teacher'),
path('login', LoginView.as_view(), name='login'),
path('logout', LogoutView.as_view(), name='logout'),
path('quizzes', QuizListView.as_view(), name='quizzes'),
path('quiz/create', QuizCreateView.as_view(), name='create quiz'),
path('quiz/update/<int:pk>', QuizUpdateView.as_view(), name='update quiz'),
)
I have the quiz.pk in templates as well(I tried with quiz.id, same result)
{% extends 'base.html' %}
{% block page_content %}
{% include 'classroom/student_header.html' with active='new' %}
<div class="card">
<table class="table mb-0">
<thead>
<tr>
<th>Quiz</th>
<th>Subject</th>
<th>Length</th>
<th></th>
</tr>
</thead>
<tbody>
{% for quiz in quizzes %}
<tr>
<td class="align-middle">{{ quiz.name }}</td>
<td class="align-middle">{{ quiz.subject.get_html_badge }}</td>
<td class="align-middle"> questions</td>
<td class="text-right">
{% if request.user.type == 'Student' %}
Start quiz
{% elif request.user.type == 'Teacher' %}
<a href="{% url 'update quiz' quiz.pk %}" class="btn btn-
warning">Edit quiz</a>
Delete quiz
{% endif %}
</td>
</tr>
{% empty %}
<tr>
<td class="bg-light text-center font-italic" colspan="4">No exam
matching your interests right
now.
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
Here is the model
class Quiz(models.Model):
owner = models.ForeignKey(UniversityUser, on_delete=models.CASCADE,
related_name='quizzes')
name = models.CharField(max_length=QUIZ_NAME_MAX_LENGTH, unique=True)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE,
related_name='quizzes')
def __str__(self):
return self.name
And here is the template I am using for the UpdateView:
{% extends 'base.html' %}
{% block page_content %}
<h2 class="mb-3">
{{ quiz.name }}
<a href="{% url 'teachers:quiz_results' quiz.pk %}" class="btn btn-primary float-
right">View results</a>
</h2>
<div class="row mb-3">
<div class="col-md-6 col-sm-8 col-12">
<form method="post" action="{% url 'update quiz' quiz.pk %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-success">Save changes</button>
<a href="{% url 'quizzes' %}" class="btn btn-outline-secondary"
role="button">Nevermind</a>
Delete
</form>
</div>
</div>
<div class="card">
<div class="card-header">
<div class="row">
<div class="col-10">
<strong>Questions</strong>
</div>
<div class="col-2">
<strong>Answers</strong>
</div>
</div>
</div>
<div class="list-group list-group-flush list-group-formset">
{% for question in questions %}
<div class="list-group-item">
<div class="row">
<div class="col-10">
{{ question.text }}
</div>
<div class="col-2">
{{ question.answers_count }}
</div>
</div>
</div>
{% empty %}
<div class="list-group-item text-center">
<p class="text-muted font-italic mb-0">You haven't created any
questions yet. Go ahead and add the first question.</p>
</div>
{% endfor %}
</div>
<div class="card-footer">
Add question
</div>
</div>
{% endblock %}
If you have any ideas why this is happening please leave a comment thanks! :)
i'm not sure but is that class you inherit from is right?
try to import :
from django.views.generic.edit import UpdatView
class QuizUpdateView(UpdateView):
I am attempting to populate a table with a filtered set of data from my Manifests model using a url parameter.
I believe that the problem I am having is in the Views.py line
manifests = Manifests.objects.all().filter(reference=reference_id)
Models.py
class Manifests(models.Model):
reference = models.ForeignKey(Orders)
cases = models.IntegerField()
description = models.CharField(max_length=1000)
count = models.IntegerField()
def __str__(self):
return self.description
Urls.py
url(r'^add_manifest/(?P<reference_id>\d+)/$', add_manifest, name='add_manifest'),
Views.py
def add_manifest(request, reference_id):
if request.method == "POST":
form = CreateManifestForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
try:
order = Orders.objects.get(id=reference_id)
except Orders.DoesNotExist:
pass
instance.reference = order
instance.save()
return redirect('add_manifest', reference_id=reference_id)
form = CreateManifestForm()
#manifests = Manifests.objects.all()
manifests = Manifests.objects.all().filter(reference=reference_id)
context = {
'form': form,
'reference_id': reference_id,
'manifests' : manifests,
}
return render(request, 'add_manifest.html', context)
template (add_manifest.html)
{% extends 'base.html' %}
{% block body %}
<div class="container">
<form method="POST">
<br>
<br>
<br>
{% csrf_token %}
<div class="column">
<label for="form.reference">Reference ID: </label><br>
<input type="text" value="{{ reference_id }}">
<br>
</div>
<div class="description">
<div class="column">
<label for="form.description">Description: </label>
<br>
{{ form.description}}
</div>
</div>
<div class="column">
<label for="form.cases">Cases: </label>
<br>
{{ form.cases }}
<br>
</div>
<div class="column">
<label for="form.count">Count: </label>
<br>
{{ form.count }}
<br>
<br>
</div>
<br>
<br>
<button type="submit" name="add_mani" style="border-color: #7395AE;">Add Line</button>
</form>
<br>
<h4>Manifest</h4>
<div class="table-responsive">
<table class="table table-striped table-bordered manifest_table" cellspacing="0" style="width="100%">
<thead>
<tr>
<th></th>
<th style="width:10%;">Ref ID</th>
<th style="width:10%;">Cases</th>
<th style="width:60%;">Description</th>
<th style="width:10%;">Count</th>
</tr>
</thead>
<tbody>
{% for manifests in manifests %}
<tr>
<td>
Edit
</td>
<td>{{ manifests.reference }}</td>
<td>{{ manifests.cases }}</td>
<td>{{ manifests.description}}</td>
<td>{{ manifests.count}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary" name="button" align="right">Subit Manifest</button>
</div>
</div>
I want the table to display only lines where the reference in the Manifests model = the reference_id in the URL. Currently it does not work as such, the table is just empty.
Change the for-loop variable name like this:
{% for manifest in manifests %}
<tr>
<td>
Edit
</td>
<td>{{ manifest.reference }}</td>
<td>{{ manifest.cases }}</td>
<td>{{ manifest.description}}</td>
<td>{{ manifest.count}}</td>
</tr>
{% endfor %}
If there is any Manifest object for reference_id, then it will render them in template.
Update
Its possible that your form is not validating. So its a good idea to render form errors:
# view
def add_manifest(request, reference_id):
form = CreateManifestForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
instance = form.save(commit=False)
try:
order = Orders.objects.get(id=reference_id)
instance.reference = order
except Orders.DoesNotExist:
pass
instance.save()
manifests = Manifests.objects.all().filter(reference=reference_id)
context = {
'form': form,
'reference_id': reference_id,
'manifests' : manifests,
}
return render(request, 'add_manifest.html', context)
And update template to show the errors in template as well:
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div>
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div>
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
I have a registration page for teachers having fields like email, mobile number, password etc, the table is named as Teacher.
I want to login page too for the same.
What I am doing is:
Added following in url page:
url(r'^login/$', auth_views.login, {'template_name': 'login.html'},name='login'),
Added following in settings.py:
AUTH_USER_MODEL = 'myapp.Teacher'
Added login.html:
{% extends "base.html" %}
{% load widget_tweaks %}
{% block body_block %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account doesn't have access to this page. To proceed,
please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %}
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="login-panel panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Please Sign In</h3>
</div>
<div class="panel-body">
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<p class="bs-component">
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
</p>
<p class="bs-component">
<center>
<input class="btn btn-success btn-sm" type="submit" value="login" />
</center>
</p>
<input type="hidden" name="next" value="{{ next }}" />
</form>
</div>
</div>
</div>
</div>
</div>
{%endblock body_block%}
Now the login page doesn't work, giving me error:
AttributeError: type object 'Teacher' has no attribute 'REQUIRED_FIELDS'
How can I implement custom login page in django?
I have two forms login.html and register.html, and i follow the same methods for displaying errors in templates, but does not work.
login.html
<form method="post" action="" class="ui large form">
{% csrf_token %}
<div class="ui stacked segment">
{% if not form.non_field_errors %}
<div class="required field">
<label>Emailaddress</label>
{{ form.username }}
</div>
{% endif %}
{% if form.non_field_errors %}
<div class="required field error">
<label>Emailaddress</label>
{{ form.username }}
</div>
{% endif %}
{% if not form.non_field_errors %}
<div class="required field">
<label>Password</label>
{{ form.password }}
</div>
{% endif %}
{% if form.non_field_errors %}
<div class="required field error">
<label>Password</label>
{{ form.password }}
</div>
{% endif %}
<small><p>{{ form.non_field_errors }}</p></small>
<input type="submit" name="" class="ui fluid large teal submit button" value="login">
</div>
</form>
Output screenshots:
Non Error output
Error output
register.html
<form method="post" action="" class="ui large form">
{% csrf_token %}
<div class="ui stacked segment">
{% if not form.non_field_errors %}
<div class="required field">
<label>Emailaddress</label>
{{ form.email }}
</div>
{% endif %}
{% if form.non_field_errors %}
<div class="required field error">
<label>Emailaddress</label>
{{ form.email }}
<p>{{ form.email.errors }}</p>
</div>
{% endif %}
{% if not form.non_field_errors %}
<div class="required field">
<label>Password</label>
{{ form.password1 }}
</div>
{% endif %}
{% if form.non_field_errors %}
<div class="required field error">
<label>Password</label>
{{ form.password1 }}
<p>{{ form.password1.errors }}</p>
</div>
{% endif %}
{% if not form.non_field_errors %}
<div class="required field">
<label>Confirm Password</label>
{{ form.password2 }}
</div>
{% endif %}
{% if form.non_field_errors %}
<div class="required field error">
<label>Confirm Password</label>
{{ form.password2 }}
<p>{{ form.password2.errors }}</p>
</div>
{% endif %}
<small><p>{{ form.non_field_errors }}</p></small>
<input type="submit" name="" class="ui fluid large teal submit button" value="Sign Up">
</div>
</form>
This time i don't get any error messages displayed. What am i doing wrong?
non_field_errors(), as their name implies, show errors not associated with a field (docs).
Note that any errors raised by your Form.clean() override will not be associated with any field in particular. They go into a special “field” (called all), which you can access via the non_field_errors() method if you need to.
You shouldn't be using it as logic for whether a specific field has an error. You should be doing this:
{% if not form.email.errors %}
<div class="required field">
<label>Emailaddress</label>
{{ form.email }}
</div>
{% endif %}
and then in your login.html, you're not rendering {{ field.errors }} like you do in register.html:
{% if form.non_field_errors %}
<div class="required field error">
<label>Emailaddress</label>
{{ form.username }}
{# This is missing #}
<p>{{ form.username.errors }}</p>
</div>
{% endif %}
I am new to django , please bear with me ..
created a template using django formsets and it works all good except i am not able to give header to the can_delete column .
My Django views.py looks like :
def add_expenditure(request):
context = RequestContext(request)
ExpFormSet = modelformset_factory(Expenditure,extra=1,max_num=10,fields=('exp_date', 'description','amount'),can_delete=True)
if request.method == 'POST':
formset = ExpFormSet(request.POST)
if formset.is_valid():
formset.save(commit=True)
formset = ExpFormSet()
else:
print "errors in formset are ",formset.errors
else:
formset = ExpFormSet(queryset=Expenditure.objects.none())
return render_to_response('moni/add_expenditure.html', {'formset':formset}, context)
templete form code is as below :
<form id="expenditure_form" method="post" action="/moni/add_expenditure/">
{% csrf_token %}
<table border=10>
<tr>
<th>Serial No.</th>
<th><label >Date:</label></th>
<th><label for="id_description">Description:</label></th>
<th><label for="id_amount">Amount</label></th>
</tr>
{{ formset.management_form }}
{% for form in formset %}
<tr>
<td>{{forloop.counter}}</td>
{% for field in form %}
<td> {{ field.class }} {{ field }}
{% if field.name == "exp_date" %}
<a href="javascript:void(0)" class="todaylink" id= {{forloop.parentloop.counter0}} >Today</a>
{% endif %}
</td>
{% endfor %}
</tr>
<br>
{% endfor %}
</table>
<input type="submit" name="submit" value="Create Expenditure" />
</form>
and template looks like :
What i want is to have a header for delete check box as well .. just next to amount . I tried adding one more header but seems its not working as intended . Can someone provide any advices .. Below is how it looks after adding one more header
<form id="expenditure_form" method="post" action="/moni/add_expenditure/">
{% csrf_token %}
<table border=10>
<tr>
<th>Serial No.</th>
<th><label >Date:</label></th>
<th><label for="id_description">Description:</label></th>
<th><label for="id_amount">Amount</label></th>
<th><label for="id_delete">Delete</label></th>
</tr>
{{ formset.management_form }}
{% for form in formset %}
<tr>
<td>{{forloop.counter}}</td>
{% for field in form %}
<td> {{ field.class }} {{ field }}
{% if field.name == "exp_date" %}
<a href="javascript:void(0)" class="todaylink" id= {{forloop.parentloop.counter0}} >Today</a>
{% endif %}
</td>
{% endfor %}
</tr>
<br>
{% endfor %}
</table>
<input type="submit" name="submit" value="Create Expenditure" />
</form>
Any Advice as to how to create this header above delete check box ?
The problem is
{% for field in form %}
<td> {{ field.class }} {{ field }}
{% if field.name == "exp_date" %}
<a href="javascript:void(0)" class="todaylink" id= {{forloop.parentloop.counter0}} >Today</a>
{% endif %}
</td>
{% endfor %}
This create 5 TD and you have 4 TD in header.
Please try this
<tr>
<th>Serial No.</th>
<th><label >Date:</label></th>
<th><label for="id_description">Description:</label></th>
<th><label for="id_amount">Amount</label></th>
<th></th>
<th><label for="id_delete">Delete</label></th>
</tr>
Also you can remove element before delete checkbox.