[PYTHON] Divisez les données en unités de type projet avec Django

Préface

Contenu de l'article

Ce que tu fais

――C'est un outil pour aider au plan de répétition de la pièce. «L'unité de type projet» mentionnée dans le titre est ici «performance». ――Pour chaque représentation, gérez le planning des formations, les acteurs, les personnages, les scènes, etc. ---> Dépôt GitHub (Python 3.8.1, Django 3.0.3)

Concept d'article

«Je n'ai pas trouvé d'échantillon de ce que je voulais faire sur le net, alors j'y ai pensé moi-même et l'ai implémenté. Partagez-le «Si vous connaissez un meilleur moyen, je vous serais reconnaissant de bien vouloir me le dire.

Pièces de base

Commencez par créer des «performances» et des «utilisateurs de performances», et répertoriez les performances dans lesquelles l'utilisateur connecté est impliqué.

Modèle de performance (unité de projet)

Le seul champ est «nom».

production/models.py


from django.db import models

class Production(models.Model):
    name = models.CharField('Nom de la performance', max_length=50)

    def __str__(self):
        return self.name

Modèle utilisateur de performance

C'est un utilisateur pour chaque performance. Le ForeignKey fait référence aux performances et aux utilisateurs (utilisateurs gérés par Django) et définit des champs pour les permissions. Veuillez consulter ici pour ʻAUTH_USER_MODEL`. Dans cet exemple, lorsqu'une performance ou un utilisateur est supprimé, l'utilisateur de performance est également supprimé.

production/models.py


from django.conf import settings

class ProdUser(models.Model):
    '''Utilisateurs et privilèges pour chaque performance
    '''
    production = models.ForeignKey(Production, verbose_name='Performance',
        on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
        verbose_name='Utilisateur', on_delete=models.CASCADE)
    is_owner = models.BooleanField('La possession', default=False)
    is_editor = models.BooleanField('Droits d'édition', default=False)

Vue de la liste des performances

Il s'agit d'une liste de performances dans lesquelles l'utilisateur connecté est impliqué. ʻObtenir le "utilisateur de performance" de telle sorte que le champ utilisateursoit l'utilisateur connecté. Vous pouvez également l'obtenir en faisant un back-référencement à partir deself.request.user`.

Puisque le nom de la performance et l '«ID de performance» peuvent être utilisés indirectement, nous afficherons la liste des performances. En d'autres termes, si vous disposez des données utilisateur relatives aux performances, vous n'avez pas besoin d'obtenir les performances elles-mêmes.

production/views.py


from django.views.generic import ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import ProdUser

class ProdList(LoginRequiredMixin, ListView):
    '''Vue de la liste de production
    
Le modèle est ProdUser car seules les performances de l'utilisateur connecté sont affichées.
    '''
    model = ProdUser
    template_name = 'production/production_list.html'
    
    def get_queryset(self):
        '''Filtrer les enregistrements affichés dans la liste
        '''
        #Obtenez votre propre ProdUser
        prod_users = ProdUser.objects.filter(user=self.request.user)
        return prod_users

Si vous écrivez un modèle d'URL et un modèle appropriés, ajoutez «Performance» et «Performance User» sur l'écran Admin et connectez-vous, une liste des performances pour lesquelles cette personne est l'utilisateur sera affichée.

Liste des performances.png

-> Le modèle ressemble à ceci

Faire une nouvelle performance

L'outil de gestion des tâches est comme la création d'un nouveau projet.

Afficher pour ajouter des performances

Si vous regardez le modèle "Liste des performances" ci-dessus, vous verrez un lien appelé "Nouveau". J'appuie sur ceci pour faire apparaître la vue suivante. Aucun paramètre requis.

production/views.py


from django.views.generic.edit import CreateView
from .models import Production

class ProdCreate(LoginRequiredMixin, CreateView):
    '''Vue supplémentaire de la production
    '''
    model = Production
    fields = ('name',) #Le seul élément de modification est le nom
    template_name_suffix = '_create'
    success_url = reverse_lazy('production:prod_list') #Après l'ajout, accédez à la liste
    
    def form_valid(self, form):
        '''Une fois la validation réussie
        '''
        #Obtenez l'enregistrement sauvegardé
        new_prod = form.save(commit=True)
        
        #Ajoutez-vous en tant que propriétaire à l'utilisateur de performance
        prod_user = ProdUser(production=new_prod, user=self.request.user,
            is_owner=True)
        prod_user.save()
        
        messages.success(self.request, str(new_prod) + "est créé.")
        return super().form_valid(form)
    
    def form_invalid(self, form):
        '''Lorsque l'ajout échoue
        '''
        messages.warning(self.request, "Impossible de créer.")
        return super().form_invalid(form)

La page est simple car le champ n'est que «nom» (nom de la performance), mais l'utilisateur correctement connecté devient «l'utilisateur de la performance» et en est également propriétaire.

Nouvelle performance.png

-> Le modèle ressemble à ceci

Désormais, l'utilisateur connecté peut créer sa propre «performance».

Vue de dessus de chaque représentation

Cliquez sur chaque performance dans la liste des performances pour passer à la vue de dessus de cette performance. De là, chaque représentation sera un monde différent.

En regardant le modèle de liste de performances ci-dessus, le nom de la performance est le lien qui ouvre la vue de dessus de cette «performance».

production/templates/production/production_list.html


    <tr>
        <td>
            <a href="{% url 'rehearsal:rhsl_top' prod_id=item.production.id %}">
                {{ item.production }}</a>
        </td>
        <td>{{ item.is_owner }}</td>
        <td>{{ item.is_editor }}</td>
    </tr>

J'ai créé la vue de dessus dans une application appelée «répétition», donc le lien ressemble à ceci. Ce lien nécessite un "identifiant de performance" comme paramètre (le nom du paramètre dans le code est "prod_id"). Puisque l'élément affiché est un "utilisateur de performance", passez ʻitem.production.id` à l '"ID de performance".

La vue est un écran de menu simple.

rehearsal/views/views.py


from django.views.generic import TemplateView
from django.core.exceptions import PermissionDenied
from .view_func import *

class RhslTop(LoginRequiredMixin, TemplateView):
    '''Première page de répétition
    '''
    template_name = 'rehearsal/top.html'
    
    def get(self, request, *args, **kwargs):
        '''Gestionnaire qui a reçu la demande au moment de l'affichage
        '''
        #Obtenez des utilisateurs performants à partir des informations d'accès et inspectez les droits d'accès
        prod_user = accessing_prod_user(self)
        if not prod_user:
            raise PermissionDenied
        
        #Avoir la production comme attribut de vue
        self.production = prod_user.production
        
        return super().get(request, *args, **kwargs)

La raison pour laquelle "production" (objet "performance") comme attribut de vue est de s'y référer à partir du modèle.

ʻAccessing_prod_user () `est une fonction définie dans un autre module appelé view_func.py et est connecté. Si l'utilisateur de est l'utilisateur de la performance, l'objet "utilisateur de la performance" est renvoyé.

rehearsal/views/view_func.py


from production.models import ProdUser

def accessing_prod_user(view, prod_id=None):
    '''Obtenez le producteur correspondant à partir des informations d'accès
    
    Parameters
    ----------
    view : View
Vue à partir de laquelle les informations d'accès sont obtenues
    prod_id : int
Prod dans URLconf_Précisez s'il n'y a pas d'identifiant
    '''
    if not prod_id:
        prod_id=view.kwargs['prod_id']
    prod_users = ProdUser.objects.filter(
        production__pk=prod_id, user=view.request.user)
    if len(prod_users) < 1:
        return None
    return prod_users[0]

Si l'utilisateur connecté n'est pas un utilisateur de performance, il renvoie «Aucun», ce qui permet le contrôle d'accès.

Haut de répétition.png

-> Les modèles ressemblent à ceci

C'est juste une liste de liens, mais chaque lien a un paramètre prod_id.

Données appartenant à la performance

Maintenant que nous avons les bases pour diviser les données en unités appelées «performances», nous serons en mesure de traiter les données appartenant à chaque performance.

Modèle d'acteur

Ce sont les données des acteurs impliqués dans la performance. Les données appartenant à la performance doivent avoir une «ForeignKey» appelée «production» pour décider à quelle performance elles appartiennent.

rehearsal/models.py


class Actor(models.Model):
    '''acteur
    '''
    production = models.ForeignKey(Production, verbose_name='Performance',
        on_delete=models.CASCADE)
    name = models.CharField('Nom', max_length=50)
    short_name = models.CharField('Nom abrégé', max_length=5, blank=True)
    
    class Meta:
        verbose_name = verbose_name_plural = 'acteur'
    
    def __str__(self):
        return self.name
    
    def get_short_name(self):
        return self.short_name or self.name[:3]

short_name (nom court) est utilisé lors de l'affichage sous forme de tableau.

Vue de la liste des acteurs

C'est une vue qui passe de la vue de dessus de la performance en cliquant sur "Liste des acteurs". Bien entendu, seuls les acteurs de la performance sont affichés, et il ne peut être vu par personne d'autre que «l'utilisateur de la performance» de la performance.

Avant de regarder la liste des acteurs, jetons un coup d'œil au lien vers la liste des acteurs dans la vue de dessus de la performance.

rehearsal/templates/rehearsal/top.html


<li><a href="{% url 'rehearsal:actr_list' prod_id=view.production.id %}">
Liste des acteurs</a></li>

Puisque nous avions le production (objet" performance ") comme attribut de vue, nous pouvons obtenir l '" ID de performance "sous la forme view.production.id. En le passant au paramètre prod_id, vous serez redirigé vers la liste des acteurs pour cette performance.

Jetons maintenant un œil à la liste des acteurs.

rehearsal/views/views.py


class ActrList(ProdBaseListView):
    '''Vue en liste des acteurs
    '''
    model = Actor
    
    def get_queryset(self):
        '''Filtrer les enregistrements affichés dans la liste
        '''
        prod_id=self.kwargs['prod_id']
        return Actor.objects.filter(production__pk=prod_id)\
            .order_by('name')

Le ProdBaseListView hérité est une classe abstraite pour afficher une liste de données appartenant à une performance. Puisque nous allons créer d'autres vues comme celle-ci, nous avons mis en place une classe abstraite pour le contrôle d'accès et ainsi de suite. Voyons cela aussi.

rehearsal/views/views.py


class ProdBaseListView(LoginRequiredMixin, ListView):
    '''Classe de base ListView pour vérifier les autorisations
    '''
    def get(self, request, *args, **kwargs):
        '''Handler pour recevoir la demande au moment de l'affichage
        '''
        #Obtenez des utilisateurs performants à partir des informations d'accès et inspectez les droits d'accès
        prod_user = accessing_prod_user(self)
        if not prod_user:
            raise PermissionDenied
        
        #Avoir le ProdUser accédant comme attribut de vue
        #Pour décider d'ajouter ou non un bouton dans le modèle
        self.prod_user = prod_user
        
        return super().get(request, *args, **kwargs)
    
    def get_context_data(self, **kwargs):
        '''Modifier les paramètres passés au modèle
        '''
        context = super().get_context_data(**kwargs)
        
        #bouton retour,Bouton Prod pour ajouter_Définir l'identifiant
        context['prod_id'] = self.kwargs['prod_id']
        
        return context

L'ID de performance (prod_id) est inclus dans context afin qu'il puisse être facilement référencé à partir du modèle. Vous pouvez vous y référer en tapant «view.prod_user.production.id» sans le mettre en «contexte», mais c'est long.

-> Le modèle ressemble à ceci

Ajoutons quelques "acteurs" sur l'écran Admin pour afficher la liste des acteurs.

Liste des acteurs.png

Afficher pour ajouter des acteurs

Si vous regardez le modèle "Liste des acteurs" ci-dessus, vous verrez un lien appelé "Ajouter". Et il ne s'affiche que pour les utilisateurs qui possèdent ou modifient la performance. Bien sûr, les utilisateurs qui ne peuvent pas voir le lien peuvent ouvrir l'URL directement dans le navigateur, donc un contrôle d'accès est également requis pour la vue à laquelle l'acteur est ajouté.

Encore une fois, nous créons une classe abstraite similaire à ProdBaseListView ci-dessus. Regardons d'abord la classe abstraite.

rehearsal/views/views.py


class ProdBaseCreateView(LoginRequiredMixin, CreateView):
    '''CreateView Base classe pour vérifier les autorisations
    '''
    def get(self, request, *args, **kwargs):
        '''Handler pour recevoir la demande au moment de l'affichage
        '''
        #Inspectez les droits de modification pour accéder aux utilisateurs
        prod_user = test_edit_permission(self)
        
        #Avoir la production comme attribut de vue
        #Pour afficher comme élément fixe dans le modèle
        self.production = prod_user.production
        
        return super().get(request, *args, **kwargs)
    
    def post(self, request, *args, **kwargs):
        '''Le gestionnaire recevra la demande lors de l'enregistrement
        '''
        #Inspectez les droits de modification pour accéder aux utilisateurs
        prod_user = test_edit_permission(self)
        
        #Avoir la production comme attribut de vue
        #À définir dans l'instance lors de l'enregistrement
        self.production = prod_user.production
        
        return super().post(request, *args, **kwargs)
    
    def form_valid(self, form):
        '''Une fois la validation réussie
        '''
        #Définissez la production de l'enregistrement que vous souhaitez ajouter
        instance = form.save(commit=False)
        instance.production = self.production
        
        messages.success(self.request, str(instance) + "Ajoutée.")
        return super().form_valid(form)
    
    def form_invalid(self, form):
        '''Lorsque l'ajout échoue
        '''
        messages.warning(self.request, "Il n'a pas pu être ajouté.")
        return super().form_invalid(form)

test_edit_permission () est une fonction définie dans view_func.py par l'utilisateur connecté. Si vous possédez ou modifiez la performance, elle renvoie l '"utilisateur de la performance".

def test_edit_permission(view, prod_id=None):
    '''Vérifier les droits d'édition
    
    Returns
    -------
    prod_user : ProdUser
Accéder à ProdUser disposant des droits de modification
    '''
    #Obtenez des utilisateurs performants à partir des informations d'accès
    prod_user = accessing_prod_user(view, prod_id=prod_id)
    if not prod_user:
        raise PermissionDenied
    
    #Refuser l'accès si vous ne disposez pas des droits de propriété ou de modification
    if not (prod_user.is_owner or prod_user.is_editor):
        raise PermissionDenied
    
    return prod_user

Les permissions sont vérifiées à la fois lors de l'affichage de la vue (méthode get) et en appuyant sur le bouton" Ajouter "pour un traitement supplémentaire (méthode post).

De plus, cette classe abstraite implémente également le processus commun de "lors de l'ajout de données appartenant à une performance, définir la performance dans le champ" production "".

Jetons maintenant un œil à l'ajout d'acteurs.

rehearsal/views/views.py


class ActrCreate(ProdBaseCreateView):
    '''Vue supplémentaire de l'acteur
    '''
    model = Actor
    fields = ('name', 'short_name')
    
    def get_success_url(self):
        '''Donner dynamiquement la destination de la transition lorsque l'ajout est réussi
        '''
        prod_id = self.production.id
        url = reverse_lazy('rehearsal:actr_list', kwargs={'prod_id': prod_id})
        return url

Après l'ajout, vous serez renvoyé à la liste des acteurs "pour cette performance".

Ajouter un acteur.png

-> Le modèle ressemble à ceci

Résumé

C'est un outil qui assiste le plan d'entraînement de la pièce, et j'ai fait plusieurs "performances" et séparé les données pour chaque performance. ――Nous avons créé un modèle appelé "Performance User" afin que l'accès puisse être contrôlé pour chaque utilisateur (utilisateur géré par Django).

J'ai écrit la suite

Recommended Posts

Divisez les données en unités de type projet avec Django (3)
Divisez les données en unités de type projet avec Django
Divisez les données en unités de type projet avec Django (2)
Utilisez Django pour enregistrer les données de tweet
Gérez vos données avec AWS RDS
Votre propre client Twitter réalisé avec Django
Diviser le japonais (katakana) en syllabes [Python]
Création de la première application avec Django startproject
Générer et publier des données d'image factice avec Django
Transformez les données de vacances en une trame de données avec les pandas
Entraînez Stanford NER Tagger avec vos propres données
Internationalisation avec Django
CRUD avec Django
Essayez de diviser les données Twitter en SPAM et HAM
Authentification unique à l'application Django avec AWS SSO
Divisez l'ensemble de données (ndarray) en proportions arbitraires avec NumPy