Attention Le code présenté n'est en aucun cas lié au code officiel du projet Sketchfab mais fait part d'un processus d'entretien.
Warranty The code from this project has no link with the official code of Sketchfab project but it is part of a job interview
Voici ma solution que je vous propose pour l'exercice que vous m'avez posé suite à notre premier entretien.
- Partir d'une structure Django vierge ok
- Rajouter les users + un model Model3d() qui représente un modèle 3d ok
- Implémenter une fonctionnalité de 'badges'
- il existe plusieurs types de badge, chacun étant décerné pour une action ou série d'action effectuée par l'utilisateur sur le site
- La liste des badges qu'un user a obtenu doit être accessible via l'api ok
- Le backend doit "décerner" les badges aux users (ie: détecter quand une action a été réalisée et donner le badge au user)
- Badges a implémenter (liste non limitative):
- Star: le modèle d'un user a plus de 1k views ok
- Collector: un user a uploadé plus de 5 modèles ok
- Pionneer: le user est inscrit depuis plus de 1 an sur le site ok
- il existe plusieurs types de badge, chacun étant décerné pour une action ou série d'action effectuée par l'utilisateur sur le site
Le projet se nomme sketchfab_test_badges et l'application badges_handler.
creation d'un environnement virtuel, installation des dépendances et tests
$ mkvirtualenv skechfab_exercice
$ cd sketchfab_test_badges
$ pip install -r requirements.txt
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py test badges_handler
$ python manage.py runserver
dans le fichier de settings sketchfab_test_badges/settings.py, le dictionnaire suivant permet de configurer les options des badges.
BADGES_SETTINGS = {
'star': 1000, # number of views
'pionner': ['00:00', ], # each day at theses hours, check for pionner users
'collector': 5, # number of models a user must upload to get this badge
}
-
Le badge star a été géré grace à un middleware, à chaque fois que la DetailView d'un modèle est visité, le middleware met à plus 1 son nombre de visite. Ce choix a été fait plutôt que de surcharger la fonction get_queryset de la DetailView Model3dDetailView. Il suffit en effet d'ajouter les urls cibles pour ajouter ce même badge à d'autres objets que les modèles 3d.
-
Le badge pionner est géré grâce à une tâche cron au travers de l'application django-cron. Après réflexions, pour un site avec de nombreux utilisateurs comme je pense SketchFab, une routine celery serait peut-être plus efficace.
-
le badge collector est remis au travers d'un callback associé au signal post_save sur le modèle Model3d. Lorsqu'un modèle est créé en base, son auteur est automatiquement enregistré à l'aide d'une clef étrangère. Si on suit cette clef, on peut récupérer son créateur et compter le nombre de modèles qu'il a déjà créer.
-
Pour récupérer tout les badges de l'instance creator
badges = creator.badges.all()
-
J'ai décidé d'utiliser l'application ContentType de Django pour créer une clef générique dans le modèle Badge afin de pourvoir décerner de façon générique des badges à un utilisateur ou un modèle (ainsi chaque modèle peut être indépendamment starré) ou encore être décerné à d'autres entités possibles.
-
Ajout d'un système d'authentification pour créer ses propres modèles. Les modèles de tous les utilisateurs ainsi que les profils de ces derniers sont publics. La seule page où une authentification est obligatoire est la page de création de modèle.
- django-cron: http://django-cron.readthedocs.org/en/latest/index.html
- freezegun: https://github.com/spulec/freezegun