listing d'instruments

This commit is contained in:
Lucie Galland 2021-04-01 21:27:17 +02:00
parent 5d1d3f8eff
commit 406f92098f
27 changed files with 673 additions and 1 deletions

View file

@ -52,6 +52,7 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'avatar',
'instruments',
]
MIDDLEWARE = [

View file

@ -39,6 +39,7 @@ urlpatterns += i18n_patterns(
),
path('agenda/', include('calendrier.urls',namespace='calendrier')),
path('partitions/', include('partitions.urls')),
path('instruments/', include('instruments.urls')),
path('pads/', include('pads.urls')),
path('admin/', admin.site.urls,),
path('trombonoscope/',include('trombonoscope.urls')),

View file

@ -0,0 +1,18 @@
# Generated by Django 2.2.17 on 2021-03-31 20:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestion', '0003_photo'),
]
operations = [
migrations.AlterField(
model_name='photo',
name='cat',
field=models.CharField(choices=[('home_join', 'Rejoignez nous'), ('home_contact', 'Nous Contacter'), ('home_rep', "Répertoire de l'acceuil"), ('login', 'Connexion'), ('change_membre', 'Modification du profil'), ('inscription_membre', 'Inscription'), ('home', 'Calendrier connecté'), ('liste', 'Agenda public'), ('part', 'Répertoire'), ('instru', 'Instruments'), ('n', "N'apparait pas")], default='n', max_length=127),
),
]

View file

@ -17,6 +17,7 @@ class Photo(models.Model):
('home', _('Calendrier connecté')),
('liste', _('Agenda public')),
('part', _('Répertoire')),
('instru', _('Instruments')),
('n',_("N'apparait pas"))
)

View file

@ -48,6 +48,7 @@
<li><a href="{% url 'partitions:liste' %}">{% trans "Répertoire" %}</a></li>
{% if user.is_authenticated %}
<li><a href="{% url 'trombonoscope:view' %}">{% trans "Trombonoscope" %}</a></li>
<li><a href="{% url 'instruments:liste' %}">{% trans "Instruments" %}</a></li>
<li><a href="https://photos.cof.ens.fr/index.php/Clubs-du-COF/L'Ernestophone" target="_blank">{% trans "Galerie Photo" %}</a></li>
<li><a href="{% url 'pads:list' %}">{% trans "Pads" %}</a></li>
{% if user.is_superuser or user.profile.is_chef %}

0
instruments/__init__.py Normal file
View file

8
instruments/admin.py Normal file
View file

@ -0,0 +1,8 @@
from django.contrib import admin
from .models import Instrument,Reparation
admin.site.register(Instrument)
admin.site.register(Reparation)

5
instruments/apps.py Normal file
View file

@ -0,0 +1,5 @@
from django.apps import AppConfig
class InstrumentsConfig(AppConfig):
name = 'instruments'

11
instruments/decorators.py Normal file
View file

@ -0,0 +1,11 @@
from django.contrib.auth.decorators import user_passes_test
def is_chef(user):
try:
profile = user.profile
return profile.is_chef
except:
return False
chef_required = user_passes_test(lambda u: is_chef(u))

0
instruments/forms.py Normal file
View file

View file

@ -0,0 +1,56 @@
# Generated by Django 2.2.17 on 2021-04-01 19:25
from django.db import migrations, models
import django.db.models.deletion
import django.db.models.functions.text
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Instrument',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('model', models.CharField(blank=True, max_length=100, null=True, verbose_name='Modèle')),
('prix', models.CharField(blank=True, default='', max_length=100, verbose_name='Prix')),
('etat', models.CharField(choices=[('Bon état', 'Bon état'), ('Etat moyen', 'Etat moyen'), ('Mauvais état', 'Mauvais état')], default='Bon état', max_length=100)),
('marque', models.CharField(blank=True, max_length=100, null=True, verbose_name='Marque')),
('serial', models.CharField(blank=True, default=' ', max_length=100, null=True, verbose_name='Numéro de série')),
('annee', models.CharField(blank=True, max_length=100, null=True, verbose_name="Année d'achat")),
('owner', models.CharField(default='Fanfare', max_length=100, verbose_name='Propriétaire')),
('user', models.CharField(blank=True, max_length=100, verbose_name='Utilisateur')),
('type', models.CharField(max_length=40, verbose_name='Instrument')),
('statut', models.CharField(choices=[('Disponible', 'Disponible'), ('Prêté', 'Prêté')], default='Disponible', max_length=100)),
('infos', models.TextField(blank=True, default='', verbose_name='Infos utiles')),
('infos_en', models.TextField(blank=True, default='', verbose_name='Infos utiles en anglais')),
],
options={
'verbose_name': 'Instrument',
'verbose_name_plural': 'Instruments',
'ordering': (django.db.models.functions.text.Lower('type'),),
},
),
migrations.CreateModel(
name='Reparation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateField(max_length=100, verbose_name='Date')),
('description', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Description')),
('description_en', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Description en anglais')),
('prix', models.CharField(blank=True, default='', max_length=100, verbose_name='Prix')),
('lieux', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Lieux')),
('instru', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='instruments.Instrument', verbose_name='Instrument')),
],
options={
'verbose_name': 'Réparation',
'verbose_name_plural': 'Réparations',
'ordering': ('date',),
},
),
]

View file

44
instruments/models.py Normal file
View file

@ -0,0 +1,44 @@
import os
from django.conf import settings
from django.db import models
from django.db.models.functions import Lower
from django.utils.translation import gettext_lazy as _
class Instrument(models.Model):
model = models.CharField(_("Modèle"),max_length=100,null=True,blank=True)
prix = models.CharField(_("Prix"),max_length=100,default='',blank=True)
etat = models.CharField(max_length=100,default='Bon état',choices = [('Bon état',_('Bon état')),('Etat moyen',_('Etat moyen')),('Mauvais état',_('Mauvais état'))])
marque = models.CharField(_("Marque"),max_length=100,null=True,blank=True)
serial = models.CharField(_("Numéro de série"),max_length=100,default=' ',null=True,blank=True)
annee = models.CharField(_("Année d'achat"),max_length=100,null=True,blank=True)
owner = models.CharField(_("Propriétaire"),max_length=100,default='Fanfare')
user = models.CharField(_('Utilisateur'),max_length=100,blank=True)
type = models.CharField(_("Instrument"), max_length=40, blank=False)
statut = models.CharField(max_length=100,default='Disponible',choices = [('Disponible',_('Disponible')),('Prêté',_('Prêté'))])
infos = models.TextField(_("Infos utiles"), null=False, blank=True,default="")
infos_en = models.TextField("Infos utiles en anglais", null=False, blank=True,default="")
def __str__(self):
return self.type
class Meta:
verbose_name = _('Instrument')
verbose_name_plural = _('Instruments')
ordering = (Lower('type'),)
class Reparation(models.Model):
date = models.DateField(_("Date"),max_length=100)
instru = models.ForeignKey("Instrument", on_delete=models.CASCADE,verbose_name=_("Instrument"))
description = models.CharField(_("Description"),max_length=100,default=' ',blank=True)
description_en = models.CharField(_("Description en anglais"),max_length=100,default=' ',blank=True)
prix = models.CharField(_("Prix"),max_length=100,default='',blank=True)
lieux = models.CharField(_('Lieux'),max_length=100,default=' ',blank=True)
def __str__(self):
return self.description
class Meta:
verbose_name = _('Réparation')
verbose_name_plural = _('Réparations')
ordering = ('date',)

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

View file

@ -0,0 +1,19 @@
{% extends "gestion/base.html" %}
{% load i18n %}
{%block titre %}{% trans "Ajout d'une instrument" %}{% endblock %}
{% block content %}
<div id="main">
<section class="wrapper style1">
<div class="inner">
<p><a href="{% url "instruments:liste" %}" class="button alt">{% trans "Retour à la liste" %}</a></p>
{% if envoi %}<p>{% trans "Cet instrument a été enregistré" %}.{% endif %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="{% trans "Enregistrer" %}" />
</form>
</div>
</section>
</div>
{% endblock %}

View file

@ -0,0 +1,19 @@
{% extends "gestion/base.html" %}
{% load i18n %}
{%block titre %}{% trans "Ajout d'une réparation" %}{% endblock %}
{% block content %}
<div id="main">
<section class="wrapper style1">
<div class="inner">
<p><a href="{% url "instruments:fiche_instru" pk %}" class="button alt">{% trans "Retour à la fiche" %}</a></p>
{% if envoi %}<p>{% trans "Cette réparation a été enregistrée" %}.{% endif %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="{% trans "Enregistrer" %}" />
</form>
</div>
</section>
</div>
{% endblock %}

View file

@ -0,0 +1,16 @@
{% extends "gestion/base.html" %}
{% load i18n %}
{% block titre %}{% trans "Suppression d'un instrument" %}{% endblock %}
{% block content %}
<div id="main">
<section class="wrapper style1">
<div class="inner">
<form action="" method="post">
{% csrf_token %}
<p><a href="{% url "instruments:liste" %}" class="button alt">{% trans "Retour aux instruments" %}</a></p>
<p>{% blocktrans with object=object %} Voulez vous vraiment supprimer le.a {{ object }}?{% endblocktrans %}</p>
<input type="submit" value="{% trans "Oui" %}" />
</form>
</div></section>
</div>
{% endblock %}

View file

@ -0,0 +1,16 @@
{% extends "gestion/base.html" %}
{% load i18n %}
{% block titre %}{% trans "Suppression d'une réparation" %}{% endblock %}
{% block content %}
<div id="main">
<section class="wrapper style1">
<div class="inner">
<form action="" method="post">
{% csrf_token %}
<p><a href="{% url "instruments:fiche_instru" id %}" class="button alt">{% trans "Retour à la fiche instrument" %}</a></p>
<p>{% blocktrans with object=object %} Voulez vous vraiment supprimer la réparation {{object}}?{% endblocktrans %}</p>
<input type="submit" value="{% trans "Oui" %}" />
</form>
</div></section>
</div>
{% endblock %}

View file

@ -0,0 +1,103 @@
{% extends "gestion/base.html" %}
{% load static %}
{% load i18n %}
{% load autotranslate %}
{% load halflength %}
{% block titre %}{% trans "Instruments" %}{% endblock %}
{% block content %}
<div id="main">
<section class="wrapper style1">
<div class="inner">
<span class="image fit">
{% if photo %}
<img src="{{photo.image.url}}" alt="" /> <div style="position:absolute;z-index:1;right:0;bottom:0">
{% if photo.url %}
<a href="{{photo.url}}" target="_blank" class="icon fa-copyright" style="color: {{photo.color}}"> {% if photo.auteur %}{{photo.auteur}}{%endif%}</a>
{% elif photo.auteur %}
<div class="icon fa-copyright" style="color: {{photo.color}}" > {{photo.auteur}}</div>
{% endif %}
</div>
{% else %}
<img src="{% static 'images/instruments.jpg' %}" alt="" /> <div style="position:absolute;z-index:1;right:0;bottom:0">
<div class="icon fa-copyright" style="color:#000000"> Lucas Gierzack</div>
{% endif %}
</div></span>
{% if user.profile.is_chef %}
<a href="{% url "instruments:ajouter_instru" %}" class="button alt big">{% trans "Ajouter un instrument" %}</a>
{% endif %}
<p></p>
<h4>{% trans "Instruments Disponibles :" %} </h4>
<div class="table-wrapper">
<table class="default">
<thead>
<tr>
<th>{% trans "Intrument" %}</th>
<th>{% trans "Propriétaire" %}</th>
<th>{% trans "Etat" %}</th>
</tr>
</thead>
<tbody>
{% for instrument in instrus_dispo %}
<a href="{% url "instruments:fiche_instru" instrument.id %}">
<tr>
<td> {{ instrument.type }} </td>
<td> {{ instrument.owner }} </td>
<td> {{ instrument.etat }} </td>
<td>
<a href="{% url "instruments:fiche_instru" instrument.id %}" class="button small">{% trans "Consulter" %}<a/>
{% if user.profile.is_chef %}
<a href="{% url "instruments:delete_instru" instrument.id %}" class="button small">{% trans "Supprimer" %}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</section>
<section class="wrapper style2">
<div class="inner">
<h4>{% trans "Instruments Prêtés :" %} </h4>
<div class="table-wrapper">
<table class="default">
<thead>
<tr>
<th>{% trans "Intrument" %}</th>
<th>{% trans "Propriétaire" %}</th>
<th>{% trans "Utilisateur" %}</th>
<th>{% trans "Etat" %}</th>
</tr>
</thead>
<tbody>
{% for instrument in instrus_prete %}
<tr>
<td> {{ instrument.type }} </td>
<td> {{ instrument.owner }} </td>
<td> {{ instrument.user }} </td>
<td> {{ instrument.etat}} </td>
<td>
<a href="{% url "instruments:fiche_instru" instrument.id %}" class="button small">{% trans "Consulter" %}<a/>
{% if user.profile.is_chef %}
<a href="{% url "instruments:delete_instru" instrument.id %}" class="button small">{% trans "Supprimer" %}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</section>
</div>
{% endblock %}

View file

@ -0,0 +1,114 @@
{% extends "gestion/base.html" %}
{% load i18n %}
{% load static %}
{% get_current_language as current_language %}
{% load autotranslate %}
{% block titre %}{{ instru.type }}{% endblock %}
{% block content %}
<div id="main">
<section class="wrapper style1">
<div class="inner">
<h1>{% blocktrans with type=instru.type etat=instru.etat%} {{type}} en {{etat}} {% endblocktrans%}</h1>
<div class="row">
<div class="7u 12u$(small)">
<p>{% trans "Propriétaire : "%} {{instru.owner}} <br>
{% trans "Statut : "%} {{instru.statut}} <br>
{% ifequal instru.statut 'Prêté' %}
{% trans "Utilisateur : "%} {{instru.user}} <br>
{% endifequal %}
{% trans "Marque : "%} {{instru.marque}} <br>
{% trans "Modele : "%} {{instru.model}} <br>
{% trans "Numéro de série : "%} {{instru.serial}} <br>
{% trans "Prix : "%} {{instru.prix}} <br>
{% blocktrans with annee=instru.annee %} Acheté.e en {{annee}} {% endblocktrans%}
</p>
{% if infos or infos_en %}
<h3>{% trans "Infos utiles :" %}</h3>
<div class="box">{% autotranslate current_language infos infos_en %}</div>
{% endif %}
{% if suppression %}
<p>{{ suppression }}</p>
{% endif %}
{% if not user.profile.is_chef %}
</div>
<div class="5u 12u$(small)">
{% endif %}
<h4>{% blocktrans count counter=reparations|length %}Réparation :{% plural %}Réparations {% endblocktrans %}</h4>
<div class="table-wrapper">
<table class="default">
<thead>
<tr>
<th>{% trans "Date" %}</th>
<th>{% trans "Description" %}</th>
<th>{% trans "Prix" %}</th>
<th>{% trans "lieu" %}</th>
</tr>
</thead>
<tbody>
{% for rep in reparations %}
<tr>
<td> {{ rep.date }} </td>
<td> {% ifequal current_language "fr" %}
{{ rep.description }}
{% else %}
{% if instru.description_en %}
{{ rep.description_en }}
{% else %}
{{ rep.description }}
{% endif %}
{% endifequal %} </td>
<td> {{ rep.prix }} </td>
<td> {{ rep.lieux }} </td>
{% if user.profile.is_chef %}
<td>
<a href="{% url "instruments:update_rep" rep.id %}" class="button small">{% trans "Modifier" %}</a>
<a href="{% url "instruments:delete_rep" rep.id %}" class="button small">{% trans "Supprimer" %}</a>
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
<p>
<a class='button ' href="{% url "instruments:liste" %}">Retour aux instruments</a>
{% if user.profile.is_chef %}
<a class='button ' href="{% url "instruments:ajouter_rep" instru.id %}">Ajouter une réparation</a>
{% endif %}
</p>
</div>
{% if user.profile.is_chef %}
<div class="5u 12u$(small)">
<div class="info_part">
<form action="{% url "instruments:fiche_instru" instru.id %}" id="chef-edit-form" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Enregister" />
</form>
{% else %}
{% if instru.infos %}
<div>
<h4>Infos utiles</h4>
<p>{{ infos }}</p>
</div>
{% endif %}
</div>
</div>
{% endif %}
</div>
</section>
</div>
{% endblock %}

View file

@ -0,0 +1,19 @@
{% extends "gestion/base.html" %}
{% load i18n %}
{%block titre %}{% trans "Ajout d'une réparation" %}{% endblock %}
{% block content %}
<div id="main">
<section class="wrapper style1">
<div class="inner">
<p><a href="{% url "instruments:fiche_instru" object.instru.id %}" class="button alt">{% trans "Retour à la fiche" %}</a></p>
{% if envoi %}<p>{% trans "Cette réparation a été enregistrée" %}.{% endif %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="{% trans "Enregistrer" %}" />
</form>
</div>
</section>
</div>
{% endblock %}

View file

View file

@ -0,0 +1 @@
do not delete me

View file

@ -0,0 +1,101 @@
from django.contrib.auth import get_user_model
from django.core.files import File
from django.template.defaultfilters import urlencode
from django.test import Client, TestCase
from gestion.models import ErnestoUser
from ..models import Category, Partition, PartitionSet
User = get_user_model()
def new_user(username, ernesto=False, chef=False):
u = User.objects.create_user(username=username)
ErnestoUser.objects.create(
user=u,
slug=username,
is_chef=chef,
is_ernesto=ernesto
)
return u
class TestViews(TestCase):
# TODO: add tests for upload/deletions
# TODO: test forms
def setUp(self):
# User with different access level and their clients
chef = new_user("chef", ernesto=True, chef=True)
chef_c = Client()
chef_c.force_login(chef)
ernesto = new_user("ernesto", ernesto=True)
ernesto_c = Client()
ernesto_c.force_login(ernesto)
self.client_matrix = [
(chef, chef_c),
(ernesto, ernesto_c),
(None, Client())
]
# A Partition set with 1 partition
self.pset = PartitionSet.objects.create(
category=Category.objects.first(),
nom="My PSet",
auteur="PSet author"
)
file = File(open("partitions/tests/test_file.txt"), "test file")
Partition.objects.create(nom="part1", part=file, morceau=self.pset)
def tearDown(self):
"""Remove dummy files from media/partitions/"""
for partition in self.pset.partition_set.all():
partition.delete()
def _get_restricted_page(self, url):
"""
Shorthand for testing wether a page in only accessible by ernesto
members
"""
for user, client in self.client_matrix:
# If user is not None, it is an ernesto member
resp = client.get(url)
if user:
self.assertEqual(200, resp.status_code)
else:
encoded_url = urlencode(urlencode(url))
redirection_url = "/login?next={}".format(encoded_url)
self.assertRedirects(resp, redirection_url)
def test_get_partition_sets(self):
"""The list of all partition sets can be fetched by everyone"""
for _, client in self.client_matrix:
resp = client.get("/partitions/")
self.assertEqual(200, resp.status_code)
def test_get_partitions(self):
"""
Only ernesto members can see the partitions inside of a partition set
"""
url = "/partitions/{}/{}".format(self.pset.nom, self.pset.auteur)
self._get_restricted_page(url)
def test_see(self):
"""Only ernesto members can see partitions"""
part = self.pset.partition_set.first()
url = "/partitions/{}/{}/see/{}".format(
self.pset.nom, self.pset.auteur, part.id
)
self._get_restricted_page(url)
def test_download(self):
"""Only ernesto members can download partitions"""
part = self.pset.partition_set.first()
url = "/partitions/{}/{}/{}".format(
self.pset.nom, self.pset.auteur, part.id
)
self._get_restricted_page(url)
def test_new(self):
"""Only ernesto members can create partiton sets"""
url = "/partitions/new"
self._get_restricted_page(url)

14
instruments/urls.py Normal file
View file

@ -0,0 +1,14 @@
from django.urls import path
from . import views
app_name = 'instruments'
urlpatterns = [
path('', views.liste, name='liste'),
path("delete/<int:pk>", views.InstruDelete.as_view(), name="delete_instru"),
path("delete_reparation/<int:pk>", views.delete_rep, name="delete_rep"),
path("new", views.InstruCreate.as_view(), name="ajouter_instru"),
path("new_rep/<int:pk>", views.create_rep, name="ajouter_rep"),
path("update_rep/<int:pk>", views.RepUpdate.as_view(), name="update_rep"),
path("fiche/<int:pk>",views.fiche_instru,name="fiche_instru"),
]

104
instruments/views.py Normal file
View file

@ -0,0 +1,104 @@
from django.shortcuts import render, HttpResponse, get_object_or_404, redirect, reverse
from instruments.models import Instrument,Reparation
from gestion.models import Photo
from django.contrib.auth.decorators import login_required
from django.forms.models import modelform_factory
from django.utils.safestring import mark_safe
from django.utils.text import slugify
from django.core.files import File
from django.utils.encoding import smart_str
from django.http import Http404
from instruments.decorators import chef_required
from django.conf import settings
from django.db.models import Q
import os
import zipfile
import io
from gestion.mixins import ChefRequiredMixin
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.http import HttpResponseRedirect
@login_required
def liste(request):
photo = Photo.objects.filter(cat='instru').order_by('?').first()
instrus_dispo = Instrument.objects.all().order_by('type').filter(statut='Disponible')
instrus_prete = Instrument.objects.all().order_by('type').filter(statut='Prêté')
return render(request, 'instruments/instru_liste.html', {"instrus_dispo":instrus_dispo,"instrus_prete":instrus_prete,"photo":photo})
class InstruCreate(ChefRequiredMixin, CreateView):
model = Instrument
fields = ["owner",'etat','type','marque','model','serial','annee','prix']
template_name = "instruments/create_instru.html"
success_url = reverse_lazy("instruments:liste")
@chef_required
def create_rep(request, pk):
ChefEditForm = modelform_factory(Reparation,
fields=("date","description","description_en","prix",'lieux'))
if request.method == "POST":
form = ChefEditForm(request.POST)
if form.is_valid():
rep = Reparation()
rep.date = form.cleaned_data['date']
rep.description = form.cleaned_data['description']
rep.description_en = form.cleaned_data['description_en']
rep.prix = form.cleaned_data['prix']
rep.lieux = form.cleaned_data['lieux']
rep.id_instru = get_object_or_404(Instrument, id=pk)
rep.save()
return redirect( 'instruments:fiche_instru', pk=pk)
else:
form = ChefEditForm(request.POST)
return render(request, 'instruments/create_rep.html', locals())
@chef_required
def delete_rep(request,pk):
rep = get_object_or_404(Reparation, id=pk)
id_instru = rep.instru.id
rep.delete()
suppression = _("Réparation supprimée")
return redirect('instruments:fiche_instru',pk=id_instru)
@login_required
def fiche_instru(request, pk):
instru = get_object_or_404(Instrument, id=pk)
reparations= Reparation.objects.filter(instru = pk).order_by('-date')
ChefEditForm = modelform_factory(Instrument,
fields=("statut","user","infos","type","owner","marque","model","serial","annee","prix","infos_en"))
if request.method == "POST" and request.user.profile.is_chef:
form = ChefEditForm(request.POST, instance=instru)
if form.is_valid():
form.save()
form = ChefEditForm(instance=instru)
infos = mark_safe(instru.infos)
infos_en = mark_safe(instru.infos_en)
return render(request, 'instruments/update_instru.html', locals())
class RepUpdate(ChefRequiredMixin, UpdateView):
model = Reparation
fields = ["date","description","description_en","prix",'lieux']
template_name = "instruments/update_rep.html"
def get_success_url(self):
# if you are passing 'pk' from 'urls' to 'DeleteView' for company
# capture that 'pk' as companyid and pass it to 'reverse_lazy()' function
id_instru=get_object_or_404(Reparation, id=self.kwargs['pk']).instru.id
return reverse_lazy('instruments:fiche_instru', kwargs={'pk': id_instru})
class InstruDelete(ChefRequiredMixin, DeleteView):
model = Instrument
template_name = "instruments/delete_instru.html"
success_url = reverse_lazy("instruments:liste")

View file

@ -73,7 +73,7 @@ def listepart(request, nom, auteur):
infos_en = mark_safe(p.infos_en)
return render(request, 'partitions/part.html', locals())
@login_required
@chef_required
def upload(request, nom, auteur):
if request.method == "POST":
form = UploadFileForm(request.POST, request.FILES)