Affiche une liste d'impressions de l'enfant pour le livre des parents.
Dans cms / models.py
, l'impression a défini le livre comme une clé externe.
class Impression(models.Model):
"""Impressions"""
book = models.ForeignKey(Book, verbose_name='Livres', related_name='impressions', on_delete=models.CASCADE)
comment = models.TextField('commentaire', blank=True)
Par conséquent, les impressions des enfants associées aux livres peuvent être lues comme suit à l'aide de related_name. Encore une fois, je n'écris pas SQL.
impressions = book.impressions.all().order_by('id') #Lire les impressions des enfants sur les livres
Cette fois, j'écrirai en utilisant ListView de «vue générale». Avec cela, vous pouvez facilement réaliser la pagination et ainsi de suite.
Ajoutez la description suivante à cms / views.py
.
from django.views.generic.list import ListView
:
class ImpressionList(ListView):
"""Liste des impressions"""
context_object_name='impressions'
template_name='cms/impression_list.html'
paginate_by = 2 #Page jusqu'à 2 pages par page
def get(self, request, *args, **kwargs):
book = get_object_or_404(Book, pk=kwargs['book_id']) #Lire les livres des parents
impressions = book.impressions.all().order_by('id') #Lire les impressions des enfants sur les livres
self.object_list = impressions
context = self.get_context_data(object_list=self.object_list, book=book)
return self.render_to_response(context)
Application de BootStrap,
Je fais ça. C'est un peu long.
Créez mybook / cms / templates / cms / impression_list.html
en héritant de mybook / cms / templates / cms / base_html
.
{% extends "cms/base.html" %}
{% block title %}Liste des impressions{% endblock title %}
{% block content %}
<h4 class="mt-4 border-bottom">Liste des impressions<small class="text-muted ml-3">{{ book.name }}</small></h4>
<a href="{% url 'cms:impression_add' book_id=book.id %}" class="btn btn-primary btn-sm my-3">ajouter à</a>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>ID</th>
<th>commentaire</th>
<th>opération</th>
</tr>
</thead>
<tbody>
{% for impression in impressions %}
<tr>
<td>{{ impression.id }}</td>
<td>{{ impression.comment|linebreaksbr }}</td>
<td>
<a href="{% url 'cms:impression_mod' book_id=book.id impression_id=impression.id %}" class="btn btn-outline-primary btn-sm">Réparer</a>
<button class="btn btn-outline-danger btn-sm del_confirm" data-toggle="modal" data-target="#deleteModal" data-pk="{{ impression.id }}" data-url="{% url 'cms:impression_del' book_id=book.id impression_id=impression.id %}">Effacer</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if is_paginated %}
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item"><a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">«</span><span class="sr-only">Previous</span></a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#" aria-label="Previous"><span aria-hidden="true">«</span><span class="sr-only">Previous</span></a></li>
{% endif %}
{% for linkpage in page_obj.paginator.page_range %}
{% ifequal linkpage page_obj.number %}
<li class="page-item active"><a class="page-link" href="#">{{ linkpage }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ linkpage }}">{{ linkpage }}</a></li>
{% endifequal %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="Next"><span aria-hidden="true">»</span><span class="sr-only">Next</span></a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#" aria-label="Next"><span aria-hidden="true">»</span><span class="sr-only">Next</span></a></li>
{% endif %}
</ul>
</nav>
{% endif %}
<a href="{% url 'cms:book_list' %}" class="btn btn-secondary btn-sm">Revenir</a>
{#Boîte de dialogue modale confirmant la suppression#}
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalLabel">Vérification</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<p>ID: <span id="del_pk"></span>Voulez-vous supprimer?</p>
</div>
<div class="modal-footer">
<a href="#" class="btn btn-primary" id="del_url">OK</a>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block extra_js %}
<script>
$(function() {
$('.del_confirm').on('click', function () {
$("#del_pk").text($(this).data("pk"));
$('#del_url').attr('href', $(this).data("url"));
});
});
</script>
{% endblock %}
La page de liste complétée sera la suivante. (Pourtant, cela ne fonctionnera pas à moins que vous ne fassiez le futur, alors pensez-y comme une telle image)
Ajoutez ce qui suit à cms / forms.py
.
Ici, nous allons créer un formulaire de base pour ajouter et modifier des modèles d'impression dans cms / models.py
.
:
from cms.models import Book, Impression
:
class ImpressionForm(ModelForm):
"""Forme d'impression"""
class Meta:
model = Impression
fields = ('comment', )
Ajoutez ce qui suit à cms / views.py
.
:
from cms.models import Book, Impression
from cms.forms import BookForm, ImpressionForm
:
def impression_edit(request, book_id, impression_id=None):
"""Modifier les impressions"""
book = get_object_or_404(Book, pk=book_id) #Lire les livres des parents
if impression_id: # impression_id est spécifié(Au moment de la correction)
impression = get_object_or_404(Impression, pk=impression_id)
else: # impression_id non spécifié(Au moment de l'ajout)
impression = Impression()
if request.method == 'POST':
form = ImpressionForm(request.POST, instance=impression) #Créer un formulaire à partir des données de demande POSTÉES
if form.is_valid(): #Validation du formulaire
impression = form.save(commit=False)
impression.book = book #Définir le livre des parents de cette impression
impression.save()
return redirect('cms:impression_list', book_id=book_id)
else: #Au moment de GET
form = ImpressionForm(instance=impression) #Créer un formulaire à partir d'une instance d'impression
return render(request,
'cms/impression_edit.html',
dict(form=form, book_id=book_id, impression_id=impression_id))
Créez mybook / cms / templates / cms / impression_edit.html
en héritant de mybook / templates / base_html
.
{% extends "cms/base.html" %}
{% load bootstrap4 %}
{% block title %}Modifier les impressions{% endblock title %}
{% block content %}
<h4 class="mt-4 mb-5 border-bottom">Modifier les impressions</h4>
{% if impression_id %}
<form action="{% url 'cms:impression_mod' book_id=book_id impression_id=impression_id %}" method="post">
{% else %}
<form action="{% url 'cms:impression_add' book_id=book_id %}" method="post">
{% endif %}
{% csrf_token %}
{% bootstrap_form form layout='horizontal' %}
<div class="form-group row">
<div class="offset-md-3 col-md-9">
<button type="submit" class="btn btn-primary">Envoyer</button>
</div>
</div>
</form>
<a href="{% url 'cms:impression_list' book_id=book_id %}" class="btn btn-secondary btn-sm">Revenir</a>
{% endblock content %}
La page d'ajout et de modification est la suivante. (Pourtant, cela ne fonctionnera pas à moins que vous ne fassiez le futur, alors pensez-y comme une telle image)
Ajoutez ce qui suit à cms / views.py
.
Cette fois, au lieu de l'effacer soudainement, j'ai mis en place une boîte de dialogue modale de Bootstrap et j'ai émis un message de confirmation. Cependant, le contenu de la vue est le même que celui du livre des parents.
def impression_del(request, book_id, impression_id):
"""Supprimer les impressions"""
impression = get_object_or_404(Impression, pk=impression_id)
impression.delete()
return redirect('cms:impression_list', book_id=book_id)
Ajoutez ce qui suit à cms / urls.py
.
urlpatterns = [
:
#Impressions
path('impression/<int:book_id>/', views.ImpressionList.as_view(), name='impression_list'), #liste
path('impression/add/<int:book_id>/', views.impression_edit, name='impression_add'), #enregistrement
path('impression/mod/<int:book_id>/<int:impression_id>/', views.impression_edit, name='impression_mod'), #Réparer
path('impression/del/<int:book_id>/<int:impression_id>/', views.impression_del, name='impression_del'), #Effacer
]
Ajoutez un lien pour obtenir une "liste d'impressions" du livre correspondant à partir de la liste des livres parents.
Ajoutez une ligne à mybook / cms / templates / cms / book_list.html
.
<td>
<a href="{% url 'cms:book_mod' book_id=book.id %}" class="btn btn-outline-primary btn-sm">Réparer</a>
<a href="{% url 'cms:book_del' book_id=book.id %}" class="btn btn-outline-danger btn-sm">Effacer</a>
<a href="{% url 'cms:impression_list' book_id=book.id %}" class="btn btn-outline-info btn-sm">Liste des impressions</a>
</td>
Maintenant, démarrez le serveur local, suivez la "Liste des impressions" de la "Liste des livres", et enregistrez / modifiez / supprimez les impressions.
http://127.0.0.1:8000/cms/book/
Si vous pouvez CRUD un modèle avec une relation parent-enfant comme expliqué jusqu'à présent, le reste est de savoir comment concevoir le modèle, donc je pense que vous pouvez l'appliquer pour faire diverses choses.
Continuez vers Introduction à Python Django (6).
Recommended Posts