Premiers pas avec Python Django (5)

Modèle enfant CRUD

Comment lire un enfant

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

Vue de la liste des enfants

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)

Modèle de liste enfant

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">&laquo;</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">&laquo;</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">&raquo;</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">&raquo;</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">&times;</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)

django10.jpg

Ajouter / modifier un formulaire enfant

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', )

Vue d'ajout et de modification d'enfants

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

Ajouter / modifier un modèle enfant

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)

django11.jpg

Vue de la suppression des enfants

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)

django12.jpg

Schéma d'URL enfant

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
]

Modifier la liste des parents

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>

django13.jpg

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

Premiers pas avec Python Django (1)
Premiers pas avec Python Django (3)
Introduction à Python Django (6)
Premiers pas avec Python Django (5)
Django 1.11 a démarré avec Python3.6
1.1 Premiers pas avec Python
Premiers pas avec Python
Premiers pas avec Django 1
Premiers pas avec Python
Premiers pas avec Django 2
Introduction aux fonctions Python
Premiers pas avec Django avec PyCharm
Premiers pas avec Python responder v2
Premiers pas avec les applications Web Python
Premiers pas avec Python pour les classes PHPer
Premiers pas avec Python Bases de Python
Premiers pas avec les algorithmes génétiques Python
Premiers pas avec Python 3.8 sous Windows
Premiers pas avec Python pour les fonctions PHPer
Premiers pas avec python3 # 1 Apprenez les connaissances de base
Premiers pas avec Android!
Premiers pas avec Python Web Scraping Practice
Premiers pas avec apache2
Introduction à l'optimisation
Premiers pas avec Python pour PHPer-Super Basics
Premiers pas avec Python Web Scraping Practice
Premiers pas avec Dynamo de Python boto
Premiers pas avec Spark
Premiers pas avec Pydantic
Premiers pas avec Jython
Premiers pas avec Heroku-Viewing Hello World en Python Django avec Raspberry PI 3
Démarrer avec Python avec 100 coups sur le traitement du langage
[Français] Premiers pas avec Rust pour les programmeurs Python
Django Getting Started Part 2 avec eclipse Plugin (PyDev)
Premiers pas avec AWS IoT facilement en Python
Django Getting Started Partie 3 sur Python3 & MySQL Connector
Matériel à lire lors de la mise en route de Python
Paramètres pour démarrer avec MongoDB avec python
Traduire Premiers pas avec TensorFlow
Faites Django avec CodeStar (Python3.6.8, Django2.2.9)
Introduction à Tkinter 2: Button
Lancez-vous avec Django! ~ Tutoriel ⑤ ~
Premiers pas avec PKI avec Golang ―― 4
Django Getting Started: 2_ Créer un projet
Django Premiers pas: 1_Construction de l'environnement
Faites Django avec CodeStar (Python3.8, Django2.1.15)
Python3 + Django ~ Mac ~ avec Apache
Django Getting Started: intégration 4_MySQL
Lancez-vous avec Django! ~ Tutoriel ④ ~
Lancez-vous avec Django! ~ Tutoriel ⑥ ~
Commencez avec Python! ~ ② Grammaire ~
Premiers pas avec python3 # 2 En savoir plus sur les types et les variables
Premiers pas avec Google App Engine pour Python et PHP
a commencé python
Commencez avec Python! ~ ① Construction de l'environnement ~
Lien pour commencer avec python