Partage
  • Partager sur Facebook
  • Partager sur Twitter

Ranger les données de ma db à partir d'un clique

    27 février 2024 à 13:47:41

    Bonjour,
     
    Je bloque depuis plusieurs jours... S'il vous plaît, aidez-moi à comprendre l'origine de mon problème! Il y a vraisemblablement quelque chose que je ne comprends pas bien puisque l'exécution de mon code ne fonctionne pas : lorsque je clique sur une des options de mon sélect, je veux que la liste des livres de mon catalogue soit triée de A à Z ou du plus petit au plus grand, ou bien de Z à A ou du plus grand au plus petit (selon l'option sélectionnée).  
     
    Ci-après, voici le contexte d'exécution :  
     
    Je débute avec Django. J'ai créé une application nommée "books" qui se rattache à un projet "sgbj". Le template catalog.html de mon application est appelée par le template index.html de mon projet "sgbj". Donc l'url d'affichage de mon application "books" est la même que celle utilisée par mon projet "sgbj" :  
     

    Mon ficher urls.py du projet "sgbj" 

        from django.contrib import admin
        from django.urls import path, include
        from books import views as books_views
        from . import views as project_views
        urlpatterns = [
            path('admin/', admin.site.urls),
            path('', books_views.catalog_view, name='index'),
            path('contact/', project_views.contact_view, name='contact'),
            path('publications/', include('articles.urls'), name='articles'),
        ]

    Le fichier views.py du projet "sgbj" :

    from django.shortcuts import render
        from books.views import catalog_view as books_catalog_view
        def index_view(request):
            catalog_context = books_catalog_view(request)
            books = catalog_context.get('catalog')
            return render(request, 'index.html', {'catalog': books})

    Le template index.html du projet "sgbj" :

        {% extends 'template_base.html' %}
        {% block title %}Home_page{% endblock %}
        {% block content %}
           
            {% block catalog_content %}
                <div id="catalog_content">
                    {% include 'catalog.html' %}
                </div>
            {% endblock %}
            {% block sort_books %}
            {% endblock %}
        {% endblock %}

    Le template catalog.html de l'application "books":

        {% extends 'template_base.html' %}
        {% block title %}Catalog_page{% endblock %}
        {% block content %}
            {% block sort_books %}
                <div class="sort_books">
                    Tri par : 
                    <select id="sort_lastname" class="select_books sort_lastname" name="lastname">
                        <option id="sort_lastname_author" class="sort_label" disabled selected hidden value="no_specific">auteur </option>
                        <option id="sort_lastname_AZ" class="display_asc option_transparent" value="asc">A ... Z</option>
                        <option id="sort_lastname_ZA" class="display_desc option_transparent" value="desc">Z ... A</option>
                    </select>
                    <select id="sort_title" class="select_books" name="titre">
                        <option id="sort_title_title" class="sort_label" disabled selected hidden value="no_specific">titre </option>       
                        <option id="sort_title_AZ" class="display_asc option_transparent" value="asc">A ... Z</option>
                        <option id="sort_title_ZA" class="display_desc option_transparent" value="desc">Z ... A</option>
                    </select>
                    <select id="sort_date" class="select_books" name="date">
                        <option id="sort_date_date" class="sort_label" disabled selected hidden value="no_specific">date </option>
                        <option id="sort_date_-+" class="display_asc option_transparent" value="asc">- ... +</option>
                        <option id="sort_date_+-" class="display_desc option_transparent" value="desc">+ ... -</option>
                    </select>
                </div>
            {% endblock %}
            {% block catalog_title %}
                <h1>Ma bibliothèque</h1>
            {% endblock %}
            {% for book in catalog %}
                <p class="catalog">
                    <span class="lastname">{{ book.lastname }}</span>
                    <span class="firstname">{{ book.firstname }}</span>
                    <span class="title"><b>{{ book.title }}</b></span>
                    <span>ISBN : <span class="isbn">{{ book.isbn }}</span>
                </p>
            {% endfor %}
        {% endblock %}

    La vue views.py de l'application "books" :

        from django.shortcuts import render
        from django.http import JsonResponse
        from django.db.models.functions import Lower
        from .models import Book
        def catalog_view(request):
            books = Book.objects.all()
            return render(request, 'books/catalog.html', {'catalog': books})
        def sort_books_view(request):
            if request.is_ajax() and 'selected_option' in request.GET:
                selected_column_option = request.GET.get('selected_option')
                column_mapping = {
                    'sort_lastname_AZ': 'lastname',
                    'sort_lastname_ZA': '-lastname',
                    'sort_firstname_AZ': 'firstname',
                    'sort_firstname_ZA': '-firstname',
                    'sort_title_AZ': 'title',
                    'sort_title_ZA': '-title',
                    'sort_date_-+': Lower('date'),
                    'sort_date_+-': Lower('-date'),
                }
               
                if selected_column_option in column_mapping:
                    sort_column = column_mapping[selected_column_option]
                    books = Book.objects.all().order_by(sort_column)
                    sorted_books = [{'lastname': book.lastname, 'firstname': book.firstname, 'title': book.title, 'isbn': book.isbn} for book in books]
                    return JsonResponse(sorted_books, safe=False)
                else:
                    return JsonResponse({'error': 'Option de tri non valide.'})
            else:
                return JsonResponse({'error': 'Cette vue ne peut être appelée que via AJAX.'})


    Mon script selector_books.js de l'application "books" (voir les lignes 46 à 82):

        document.addEventListener('DOMContentLoaded', function() {
            var selectElements = document.querySelectorAll('#sort_lastname, #sort_firstname, #sort_title, #sort_date');
            var defaultLabelOptions = {};
            selectElements.forEach(function(selectElement) {
                var defaultLabelOption = selectElement.querySelector('option');
                defaultLabelOptions[selectElement.id] = defaultLabelOption.textContent;
                defaultLabelOption.style.display = 'none';
                selectElement.addEventListener('change', function() {
                    var selectedOption = this.options[this.selectedIndex];
                    var optionClass = selectedOption.getAttribute('class');
                    var optionText = selectedOption.textContent;
                    selectElements.forEach(function(otherSelect) {
                        if (otherSelect !== selectElement) {
                            var defaultOption = otherSelect.querySelector('option[value="no_specific"]');
                            defaultOption.style.display = '';
                            defaultOption.selected = true;
                            otherSelect.querySelectorAll('option').forEach(function(option) {
                                option.style.display = '';
                            });
                        }
                    });   
                    // Afficher toutes les options
                    var options = selectElement.querySelectorAll('option');
                    options.forEach(function(option) {
                        option.style.display = '';   
                    });
                    // Cacher l'option sélectionnée
                    selectedOption.style.display = 'none';
                    if (optionClass === 'sort_label' || (optionText !== 'auteur A ... Z' && optionText !== 'auteur Z ... A' && optionText !== 'titre A ... Z' && optionText !== 'titre Z ... A' && optionText !== 'date - ... +' && optionText !== 'date + ... -')) {
                        selectedOption.textContent = defaultLabelOptions[selectElement.id] + optionText;
                    }
                    // Masquer les options appropriées sans masquer l'élément sélectionné
                    if (optionClass === 'display_asc') {
                        var descOptions = selectElement.parentNode.querySelectorAll('.display_desc');
                        descOptions.forEach(function(option) {
                            option.style.display = '';
                        });
                    } else if (optionClass === 'display_desc') {
                        var ascOptions = selectElement.parentNode.querySelectorAll('.display_asc');
                        ascOptions.forEach(function(option) {
                            option.style.display = '';
                        });
                    }
                });
            });
            $('#sort_lastname, #sort_firstname, #sort_title, #sort_date').on('change', function() {
                var selectedOption = $(this).val();
                if (selectedOption === "AZ" || selectedOption === "-+" || selectedOption === "ZA" || selectedOption === "+-" ) {
                    var dataToSend = {};
                    var selectedColumn = '';
                   
                    if ($(this).attr('id') === 'sort_lastname') {
                        selectedColumn = 'lastname';
                        dataToSend['selected_lastname_option'] = 'sort_' + selectedColumn + '_' + selectedOption.toUpperCase();
                        dataToSend['selected_firstname_option'] = 'sort_firstname_' + selectedOption.toUpperCase();
                    } else if ($(this).attr('id') === 'sort_firstname') {
                        selectedColumn = 'firstname';
                        dataToSend['selected_firstname_option'] = 'sort_' + selectedColumn + '_' + selectedOption.toUpperCase();
                        dataToSend['selected_lastname_option'] = 'sort_lastname_' + selectedOption.toUpperCase();
                    } else if ($(this).attr('id') === 'sort_title') {
                        selectedColumn = 'title';
                    } else if ($(this).attr('id') === 'sort_date') {
                        selectedColumn = 'date';
                    }
                   
                    $.ajax({
                        url: '',
                        data: dataToSend,
                        dataType: 'json',
                        success: function(data) {
                            updateIndexData(data, selectedColumn);
                        }
                    });
                }
            });
            function updateIndexData(data, selectedColumn) {
                $('#catalog_content .catalog p').each(function(index) {
                    $(this).find('.' + selectedColumn).text(data[index][selectedColumn]);
                    $(this).find('.isbn').text('ISBN : ' + data[index].isbn);
                });
            }
        });



    L'affichage web en local fonctionnait bien avant que j'essaye de trier les données par ordre croissant/décroissant.
    J'espère que vous voudrez bien m'aider à identifier l'origine de la non exécution de mon code!








    -
    Edité par DelphineGi 27 février 2024 à 13:51:38

    • Partager sur Facebook
    • Partager sur Twitter

    Ranger les données de ma db à partir d'un clique

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    • Editeur
    • Markdown