Can't access UpdateView in Django - python

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):

Related

improperly configured at /18/delete, Django views issue

I have searched through the other questions similar to my own problem and have come to no solution so im hoping someone can help me figure out where i went wrong.
I'm trying to implement a delete post option in my blog program but it is throwing the following error once you click the 'delete' button:
ImproperlyConfigured at /18/delete/
Deletepost is missing a QuerySet. Define Deletepost.model, Deletepost.queryset, or override Deletepost.get_queryset().
I am nearly sure its a problem with my URLS.py though what exactly i cannot figure out.
the following is the code in question:
Views.py
# delete post
class Deletepost(LoginRequiredMixin, DeleteView):
form_class = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
urls.py
urlpatterns = [
# home
path('', views.postslist.as_view(), name='home'),
# add post
path('blog_post/', views.PostCreateView.as_view(), name='blog_post'),
# posts/comments
path('<slug:slug>/', views.postdetail.as_view(), name='post_detail'),
# edit post
path('<slug:slug>/edit/', views.Editpost.as_view(), name='edit_post'),
# delete post
path('<int:pk>/delete/', views.Deletepost.as_view(), name='delete_post'),
# likes
path('like/<slug:slug>', views.PostLike.as_view(), name='post_like'),
]
post.html
{% extends 'base.html' %} {% block content %}
{% load crispy_forms_tags %}
<div class="masthead">
<div class="container">
<div class="row g-0">
<div class="col-md-6 masthead-text">
<!-- Post title goes in these h1 tags -->
<h1 class="post-title text-success">{{ post.title }}</h1>
<!-- Post author goes before the | the post's created date goes after -->
<p class="post-subtitle text-success">{{ post.author }} | {{ post.created_on }}</p>
</div>
<div class="d-none d-md-block col-md-6 masthead-image">
<!-- The featured image URL goes in the src attribute -->
{% if "placeholder" in post.featured_image.url %}
<img src="https://codeinstitute.s3.amazonaws.com/fullstack/blog/default.jpg" width="100%">
{% else %}
<img src=" {{ post.featured_image.url }}" width="100%">
{% endif %}
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col card mb-4 mt-3 left top">
<div class="card-body text-dark">
<!-- The post content goes inside the card-text. -->
<!-- Use the | safe filter inside the template tags -->
<p class="card-text text-dark">
{{ post.content | safe }}
</p>
<div class="row">
<div class="col-1">
<strong>
{% if user.is_authenticated %}
<form class="d-inline" action="{% url 'post_like' post.slug %}" method="POST">
{% csrf_token %}
{% if liked %}
<button type="submit" name="blogpost_id" value="{{post.slug}}" class="btn-like"><i class="fas fa-heart"></i></button>
{% else %}
<button type="submit" name="blogpost_id" value="{{post.slug}}" class="btn-like"><i class="far fa-heart"></i></button>
{% endif %}
</form>
{% else %}
<span class="text-secondary"><i class="far fa-heart"></i></span>
{% endif %}
<!-- The number of likes goes before the closing strong tag -->
<span class="text-secondary">{{ post.number_of_likes }} </span>
</strong>
</div>
<div class="col-1">
{% with comments.count as total_comments %}
<strong class="text-dark"><i class="far fa-comments"></i>
<!-- Our total_comments variable goes before the closing strong tag -->
{{ total_comments }}</strong>
{% endwith %}
</div>
<div class="col-1">
<a class="btn btn-outline-danger" href="{% url 'delete_post' post.id %}">Delete It</a>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<hr>
</div>
</div>
<div class="row">
<div class="col-md-8 card mb-4 mt-3 ">
<h3 class="text-dark">Comments:</h3>
<div class="card-body">
<!-- We want a for loop inside the empty control tags to iterate through each comment in comments -->
{% for comment in comments %}
<div class="comments text-dark" style="padding: 10px;">
<p class="font-weight-bold">
<!-- The commenter's name goes here. Check the model if you're not sure what that is -->
{{ comment.name }}
<span class=" text-muted font-weight-normal">
<!-- The comment's created date goes here -->
{{ comment.created_on }}
</span> wrote:
</p>
<!-- The body of the comment goes before the | -->
{{ comment.body | linebreaks }}
</div>
<!-- Our for loop ends here -->
{% endfor %}
</div>
</div>
<div class="col-md-4 card mb-4 mt-3 ">
<div class="card-body">
<!-- For later -->
{% if commented %}
<div class="alert alert-success" role="alert">
Your comment is awaiting approval
</div>
{% else %}
{% if user.is_authenticated %}
<h3 class="text-dark">Leave a comment:</h3>
<p class="text-dark">Posting as: {{ user.username }}</p>
<form class="text-dark" method="post" style="margin-top: 1.3em;">
{{ comment_form | crispy }}
{% csrf_token %}
<button type="submit" class="btn btn-signup btn-lg">Submit</button>
</form>
{% endif %}
{% endif %}
</div>
</div>
</div>
</div>
{% endblock content %}
Any ideas?
I think it should be model not form_class so:
class Deletepost(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
#SunderamDubey's answer is correct. The test_func will however not run, since this is method of the UserPassesTestMixin [Django-doc], not LoginRequiredMixin.
But using a test function as is done here is not efficient: it will fetch the same object twice from the database. You can simply restrict the queryset, like:
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.views.generic import DeleteView
class DeletePostView(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def get_queryset(self, *args, **kwargs):
return (
super().get_queryset(*args, **kwargs).filter(author=self.request.user)
)
This will do filtering at the database side, and thus return a 404 in case the logged in user is not the author of the Post object you want to delete.
In the template, you will need to make a mini-form to make a POST request, for example:
<form method="post" action="{% url 'delete_post' post.id %}">
{% csrf_token %}
<button class="btn btn-outline-danger" type="submit">Delete</button>
</form>
In my opinion, you should change url to below
'path('delete/int:pk', views.Deletepost.as_view(), name='delete_post'),'
if didn't work you can do this
def delete_post(request, post_id):
post = Post.objects.get(pk=post_id)
post.delete()
return redirect('blog:home')

Reverse for 'admin-color-product-map-edit' with arguments '('',)' not found. 1 pattern(s) tried: ['admin1/colorProductMap_edit/(?P<id>[0-9]+)$']

I'm a new face to Django so please be considerate to if ever my problem is something stupid. So I have been practicing Django, I've run into problems with tegards to NoReverseMatch, I went through answers in stackoverflow but still I couldn't find where I went wrong. Can you help me a bit guys?
views.py
#login_required(login_url="admin-login")
#user_passes_test(check_role_admin)
def colorProductMap_edit(request, id):
instance = ColorProductMapping.objects.get(color_p_map_id=id)
print(instance.color_id)
form = ColorProductMapForm(instance=instance)
if request.method == 'POST':
form = ColorProductMapForm(request.POST, instance=instance)
if form.is_valid():
form.save()
return redirect('/admin1/colorProductMap')
else:
form = ColorProductMapForm(instance=instance)
return render(request, 'admin1/colorProductMap.html', {'form': form, 'instance': instance})
I properly partnered and connected with the following in my urls.py.
urls.py
path('colorProductMap_edit/<int:id>', views.colorProductMap_edit, name="admin-color-product-map-edit"),
forms.py
class ColorProductMapForm(forms.ModelForm):
class Meta:
model = ColorProductMapping
fields = ['color_id', 'prod_id']
models.py
class ColorProductMapping(models.Model):
color_p_map_id = models.AutoField("Color & Product Map ID", primary_key=True, auto_created=True)
color_id = models.ForeignKey(Color, null=False, on_delete=models.CASCADE, verbose_name="Color ID")
prod_id = models.ForeignKey(Product, null=False, on_delete=models.CASCADE, verbose_name="Product Id")
colorProductMap.html
{% extends 'admin1/layout/master.html' %}
{% block title %}Color Product Map{% endblock %}
{% block main %}
<h1>
<center>Color Product Map</center>
</h1>
<div class="container">
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-10">
{%if colorProductMap_show%}
<button type="button" class="btn btn-primary mt-2" data-toggle="modal" data-target="#modal-primary">Add
Color Product Mapping
</button>
<div class="modal fade" id="modal-primary">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Add Color Product Mapping</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">Ă—</span></button>
</div>
<div class="modal-body mt-2">
<form action="{% url 'admin-color-product-map'%}" method="POST"
enctype="multipart/form-data">
{% csrf_token %}
<table border="1" class="table table-bordered border border-info">
<tr>
<th>
{{form.color_id.label_tag}}
</th>
<td>{{form.color_id}}</td>
</tr>
<tr>
<th>
{{form.prod_id.label_tag}}
</th>
<td>
{{form.prod_id}}
</td>
</tr>
</table>
<div class="modal-footer justify-content-right">
<input type="Submit" name="Submit" value="Submit" class="btn btn-outline-success">
<button type="button" class="btn btn-outline-danger" data-dismiss="modal">Close
</button>
</div>
</form>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
<div class="container-fluid ">
<div class="row">
<div class="card mt-2 border border-secondary">
<div class="card-header">
<h3 class="card-title ">Color Product Map Table</h3>
</div>
<!-- /.card-header -->
<div class="card-body">
<table class="table table-bordered border border-info">
<thead>
<tr>
<th>Color Product Mapping Id</th>
<th>Product ID</th>
<th>Color ID</th>
<th>Action</th>
</tr>
</thead>
<tbody class="justify-content-center">
{% for x in colorProductMap_show %}
<tr>
<td>{{x.color_p_map_id}}</td>
<td>{{x.prod_id}}</td>
<td>{{x.color_id}}</td>
<td><a href="{% url 'admin-color-product-map-edit' x.color_p_map_id %}"
class="btn btn-outline-primary mt-2"><i
class="fa fa-pencil-square-o" aria-hidden="true"></i></a>
<a href="{% url 'admin-color-product-map-delete' x.color_p_map_id %}"
class="btn btn-outline-danger mt-2"><i
class="fa fa-trash" aria-hidden="true"></i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.card-body -->
<div class="card-footer clearfix ">
<ul class="pagination pagination-sm m-0 justify-content-center">
{% if colorProductMap_show.has_previous %}
<li class="page-item"><a class="page-link"
href="?page={{colorProductMap_show.previous_page_number}}">
Previous </a>
</li>
{% endif%}
{% for x in colorProductMap_show.paginator.page_range %}
{% if colorProductMap_show.number == x %}
<li class="page-item active"><a class="page-link" href="?page={{x}}">{{x}}</a></li>
{% else%}
<li class="page-item"><a class="page-link" href="?page={{x}}">{{x}}</a></li>
{% endif %}
{% endfor %}
{% if colorProductMap_show.has_next %}
<li class="page-item"><a class="page-link"
href="?page={{colorProductMap_show.next_page_number}}">
Next </a>
</li>
{% endif %}
</ul>
</div>
</div>
<!-- /.card -->
</div>
</div>
{%endif%}
{% if instance %}
<form action="{% url 'admin-color-product-map-edit' x.color_p_map_id %}" method="POST"
enctype="multipart/form-data">
{% csrf_token %}
<table border="1" class="table table-bordered border border-info">
<tr>
<th>
{{form.color_id.label_tag}}
</th>
<td>{{form.color_id}}</td>
</tr>
<tr>
<th>
{{form.prod_id.label_tag}}
</th>
<td>
{{form.prod_id}}
</td>
</tr>
</table>
<input type="Submit" name="Submit" value="Submit" class="btn btn-success w-50"><br>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-outline-light" data-dismiss="modal">Close
</button>
</div>
</form>
{% endif %}
</div>
</div>
</div>
{% endblock %}
What am I doing wrong? I think I have followed every advice I could find, but yeah it still gives me the error. Any help is appreciated. Thank you very much!
You write your form tag as:
<form action="{% url 'admin-color-product-map-edit' x.color_p_map_id %}" method="POST"
enctype="multipart/form-data">
After observing your template and view it appears that you are using the same template for multiple views and this is causing confusion. As I note in the comment there is no x in the context for this view (In the other one you loop over a variable which doesn't exist in this view to get this). After looking a bit more one notices that by this {% url 'admin-color-product-map-edit' x.color_p_map_id %} you want to point to the current url itself. If a forms action is to the same url the best thing to do is forego the action attribute completely (If there is no action attribute the request would be to the same url as the page user is in):
<form method="POST" enctype="multipart/form-data">
Thanks all to guide me, I have found my mistake.
In the html template, as shown below
<form action="{% url 'admin-color-product-map-edit' x.color_p_map_id %}" method="POST"
enctype="multipart/form-data">
Here I am using x.color_p_map_id where x is not any iterable object so the error I was getting.
Now I have made a change and used instance instead of x in above url and now its working fine.
<form action="{% url 'admin-color-product-map-edit' instance.color_p_map_id %}" method="POST"
enctype="multipart/form-data">

Edit and Update method is working.But,how to retrieve the values from database while editing the existing values

I'm Creating Small Size of Web Interface.I created the edit button in Web Interface.But ,it's not working.It Creating as a new Entry in Database.Can anyone help me.One more thing is How to retrieve the values from database while editing existing values.Thanks for advanced.
Here is The Python Code:
class UserForm(FlaskForm):
type=StringField('type')
#app.route('/newuser', methods=['GET', 'POST'])
def add_user():
form = UserForm()
if form.validate_on_submit():
user_details = {
'type': form.type.data
}
sqlsession.add(user_details)
return redirect(url_for('vehicle_type'))
return render_template('vehicletype.html', form=form)
#app.route('/control/edit/<int:id>',methods=['POST','GET'])
def edit(id):
qry=sqlsession.query(Vehicletype).filter(Vehicletype.id==id).first()
form = UserForm(request.form, object=qry)
if form.validate_on_submit():
form.populate_obj(qry)
sqlsession.update(qry)
sqlsession.commit()
return redirect(url_for('vehicle_type'))
return render_template('vehicletype.html', form=form)
Here is the Templates of the vehicletype.html Code:
{% extends "base.html" %}
{% block head %}
{{super()}}
{% endblock %}
{% block navbar %}
{{super()}}
{% endblock %}
{% block content %}
<div class="row">
<ol class="breadcrumb">
<li><a href="#">
<em class="fa fa-home"></em>
</a></li>
<li class="active">Vehicletype > Create Vehicletype</li>
</ol>
</div><!--/.row-->
<div class="row">
<div class="col-md-6">
<form role="form" action="/post/vehicletype" method="post">
<div class="form-group">
<label>VehicleType: </label>
<input name="type" class="form-control" placeholder="enter vehicletype">
</div>
<input type="submit" class="btn btn-primary" value="Submit ">
<input type="reset" class="btn btn-default" value="Reset">
</form>
</div>
</div>
{% endblock %}
Here is the vehicletypedetails.html code:
{% extends "base.html" %}
{% block head %}
{{super()}}
{% endblock %}
{% block navbar %}
{{super()}}
{% endblock %}
{% block content %}
<div class="row">
<ol class="breadcrumb">
<li><a href="#">
<em class="fa fa-home"></em>
</a></li>
<li class="active">Vehicletype>View</li>
</ol>
</div><!--/.row-->
<div class="row">
<div class="col-md-12">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>
Id
</th>
<th>
VehicleType
</th>
<th>
Dateofsub
</th>
<!--<th>
Control
</th>-->
<th>
Delete
</th>
</tr>
</thead>
{% for values in vehicletype %}
<tr>
<th>{{values.id}}</th>
<td>{{values.type}}</td>
<td>{{values.dateofsub}}</td>
<!--<td>Reset Password</td>-->
<td>Delete</td>
<td>edit</td>
</tr>
{% endfor %}
</table>
<em class="fa fa-xl fa-plus-circle color-blue" ></em>
</div>
</div>
{% endblock %}
I have been trying to solve this issue for 6 days .But I Could not find any solution. Please could you help me anyone.
Your code to edit an existing entry has a route of /control/edit/<int:id>, but your form you're using to submit the user-changes is pointing at a different route located at /post/vehicletype.
You'll need to change your return from:
return render_template('vehicletype.html', form=form)
to:
return render_template('vehicletype.html', form=form, car_id=id)
And then change your html code from:
<form role="form" action="/post/vehicletype" method="post">
to:
<form role="form" action="{{ url_for('edit', id=car_id) }}" method="post">
With that in place, your form code will be getting submitted to the correct route for processing.

How do I fix my Createview in Django

I am trying to make a business card manager using django python but I don't why my business card is not being added. When I press the button "Add business Card", it goes to the BusinessCardListView but it is blank. I also want to know how to make the delete and update button work on the Business Card List. I think I have to add a primary key in the model but I don't know how to pass it correctly.
Views
from django.views import generic
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from django.views.generic import View
from .models import BusinessInfo
class BusinessCardListView(generic.ListView):
model = BusinessInfo
template_name = 'manager/BusinessCardList.html'
context_object_name = 'all_business_cards'
def get_queryset(self):
return BusinessInfo.objects.all()
class BusinessCardCreate(CreateView):
model = BusinessInfo
fields = ['card', 'company_name', 'phone_number', 'website', 'representative_name', 'branch_address', 'job_title',
'fax_number', 'cell_phone_number', 'email']
class BusinessCardUpdate(UpdateView):
model = BusinessInfo
fields = ['card', 'company_name', 'phone_number', 'website', 'representative_name', 'branch_address', 'job_title',
'fax_number', 'cell_phone_number', 'email']
class BusinessCardDelete(DeleteView):
model = BusinessInfo
success_url = reverse_lazy('manager:index')
Add Business Card form
{% extends 'manager/base.html' %}
{% block title %}Add a New Business Card{% endblock %}
{% block albums_active %}active{% endblock %}
{% block body %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-7">
<div class="panel panel-default">
<div class="panel-body">
<form class="form-horizontal" action="{% url 'manager:index' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'manager/form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Add Business Card</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
form_template
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.error }}</span>
</div>
<label class="control-label col-sm-2">{{ field.label_tag }}</label>
<div class="col-sm-10">{{ field }}</div>
</div>
{% endfor %}
urls
from django.conf.urls import url
from . import views
app_name = 'manager'
urlpatterns = [
url(r'^$', views.BusinessCardListView.as_view(), name='index'),
url(r'business_card/add/$', views.BusinessCardCreate.as_view(), name='business_card-add'),
url(r'business_card/(?P<pk>[0-9]+)/edit/$', views.BusinessCardUpdate.as_view(), name='edit'),
url(r'business_card/(?P<pk>[0-9]+)/delete/$', views.BusinessCardDelete.as_view(), name='delete'),
]
models
from django.db import models
from django.core.urlresolvers import reverse
# Business Card Info
class BusinessInfo(models.Model):
card = models.FileField(default='Picture')
company_name = models.CharField(max_length=100000, primary_key=True)
website = models.CharField(max_length=100000)
representative_name = models.CharField(max_length=100000)
branch_address = models.CharField(max_length=100000)
job_title = models.CharField(max_length=10000)
email = models.EmailField()
phone_number = models.CharField(max_length=100000)
fax_number = models.CharField(max_length=100000)
cell_phone_number = models.CharField(max_length=100000)
def get_absolute_url(self):
return reverse('manager:index')
def __str__(self):
return self.company_name + ':' + self.representative_name
Business Card List
{% extends 'manager/Base.html' %}
{% block body %}
<style>
table, th, .Info {
border: 1px solid black;
border-collapse: collapse;
text-align: center;
}
</style>
<table style="width:100%">
<tr>
<th>Business Card</th>
<th>Company Name</th>
<th>Representative Name</th>
<th>Job Title</th>
<th>Branch Address</th>
<th>Website</th>
<th>Phone Number</th>
<th>Cell Phone Number</th>
<th>Email</th>
<th>Fax Number</th>
</tr>
{% for businessinfo in all_business_cards %}
<tr>
<td class="Info">{{ businessinfo.card }}</td>
<td class="Info">{{ businessinfo.company_name }}</td>
<td class="Info">{{ businessinfo.representative_name }}</td>
<td class="Info">{{ businessinfo.job_title }}</td>
<td class="Info">{{ businessinfo.branch_address }}</td>
<td class="Info">{{ businessinfo.website }}</td>
<td class="Info">{{ contactinfo.phone_number }}</td>
<td class="Info">{{ contactinfo.cell_phone_number }}</td>
<td class="Info">{{ contactinfo.email }}</td>
<td class="Info">{{ contactinfo.fax_number }}</td>
<td>
<form action="{% url 'music:delete' %}" method="post" style="display: inline;">
{% csrf_token %}
<input type="hidden" name="company_name" value="{{ company_name }}"/>
<button type="submit" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-trash"></span>
</button>
</form>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}
The action attribute in your form tag inside the Business Card Create form template is {% url 'manager:index' %} which points to the BuisinessCardListView thats why it is taking you to the list view on submit.
To achieve what you want it should point the CreateView url, like this:
{% extends 'manager/base.html' %}
{% block title %}Add a New Business Card{% endblock %}
{% block albums_active %}active{% endblock %}
{% block body %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-7">
<div class="panel panel-default">
<div class="panel-body">
<form class="form-horizontal" action="{% url 'manager:business_card-add' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'manager/form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Add Business Card</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

Bootstrap accordion with Django: How to only load the data for the open accordion section?

I'm trying to make a webpage that will display recipes in the format of a bootstrap accordion like so (see here).
This is how I'm doing it as of now:
<div class="panel-group" id="accordion">
{% for recipe in recipes %}
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse{{ forloop.counter }}">
{{ recipe }}
</a>
</h4>
</div>
<div id="collapse{{ forloop.counter }}" class="panel-collapse collapse">
<div class="panel-body">
<table class="table table-hover">
{% for ingredient in foodtype|ingredients_in_recipe:recipe %}
<tr>
<td>
{{ ingredient.ingredient_name }}
</td>
<td>
{{ ingredient.ingredient_quantity }}
</td>
</tr>
{% endfor %}
<p>{{ recipe.details }}</p>
</table>
</div>
</div>
</div>
{% endfor %}
</div>
I have made a custom template tag for this like so:
#register.filter
def ingredients_in_recipe(foodtype, recipe):
return foodtype.ingredient_set.filter(recipe=recipe).order_by("ingredient_name")
The problem is that I have 200+ recipes and loading all this data is way too slow. Ideally the template tag function ingredients_in_recipe should only be called when the user clicks on the recipe. However from my understanding this isn't possible because Django runs it all then sends the rendered HTML to the user.
Is there anyway I could circumvent this issue whilst still keeping the accordion style like in the picture?
Thanks in advance,
Max
EDIT: Here's my view as well
def detail(request, foodtype_id):
foodtype = get_object_or_404(foodtype, id=foodtype_id)
recipe = foodtype.recipe_set.values_list('recipe').order_by('recipe').distinct()
context = {
'foodtype': foodtype,
'recipe': recipe,
}
return render(request, 'main/detail.html', context)
Always better to do that logic before it gets to the template. What if you set the ordering on ingredients so then you won't have to order them in the template? Does that work and improve the performance?
class Ingredient(models.Model):
...
class Meta:
ordering = ['ingredient_name']
<div class="panel-group" id="accordion">
{% for recipe in recipes %}
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse{{ forloop.counter }}">
{{ recipe }}
</a>
</h4>
</div>
<div id="collapse{{ forloop.counter }}" class="panel-collapse collapse">
<div class="panel-body">
<table class="table table-hover">
{% for ingredient in recipe.ingredient_set.all %}
<tr>
<td>
{{ ingredient.ingredient_name }}
</td>
<td>
{{ ingredient.ingredient_quantity }}
</td>
</tr>
{% endfor %}
<p>{{ recipe.details }}</p>
</table>
</div>
</div>
</div>
{% endfor %}
</div>

Categories