From 89785ce632c829bc4658d565f0c5388a86fc0796 Mon Sep 17 00:00:00 2001 From: quark Date: Fri, 17 May 2024 20:46:38 +0200 Subject: [PATCH 1/3] =?UTF-8?q?Cr=C3=A9ation=20de=20l'apps=20et=20de=20la?= =?UTF-8?q?=20base=20de=20donn=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/food/__init__.py | 0 apps/food/admin.py | 3 + apps/food/apps.py | 5 + apps/food/migrations/0001_initial.py | 96 ++++++++++ apps/food/migrations/__init__.py | 0 apps/food/models.py | 257 +++++++++++++++++++++++++++ apps/food/tests.py | 3 + apps/food/views.py | 3 + note_kfet/settings/base.py | 1 + 9 files changed, 368 insertions(+) create mode 100644 apps/food/__init__.py create mode 100644 apps/food/admin.py create mode 100644 apps/food/apps.py create mode 100644 apps/food/migrations/0001_initial.py create mode 100644 apps/food/migrations/__init__.py create mode 100644 apps/food/models.py create mode 100644 apps/food/tests.py create mode 100644 apps/food/views.py diff --git a/apps/food/__init__.py b/apps/food/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/food/admin.py b/apps/food/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/apps/food/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps/food/apps.py b/apps/food/apps.py new file mode 100644 index 00000000..092961b7 --- /dev/null +++ b/apps/food/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class FoodkfetConfig(AppConfig): + name = 'foodkfet' diff --git a/apps/food/migrations/0001_initial.py b/apps/food/migrations/0001_initial.py new file mode 100644 index 00000000..46899dd6 --- /dev/null +++ b/apps/food/migrations/0001_initial.py @@ -0,0 +1,96 @@ +# Generated by Django 2.2.28 on 2024-05-17 18:44 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('member', '0011_profile_vss_charter_read'), + ] + + operations = [ + migrations.CreateModel( + name='Allergen', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('gluten', models.BooleanField(default=False, verbose_name='gluten')), + ('nut', models.BooleanField(default=False, verbose_name='nut')), + ('crustecean', models.BooleanField(default=False, verbose_name='crustacean')), + ('celery', models.BooleanField(default=False, verbose_name='celery')), + ('egg', models.BooleanField(default=False, verbose_name='egg')), + ('mustard', models.BooleanField(default=False, verbose_name='mustard')), + ('fish', models.BooleanField(default=False, verbose_name='fish')), + ('soy', models.BooleanField(default=False, verbose_name='soy')), + ('milk', models.BooleanField(default=False, verbose_name='milk')), + ('sulphite', models.BooleanField(default=False, verbose_name='sulphite')), + ('lupine', models.BooleanField(default=False, verbose_name='lupine')), + ('mollusc', models.BooleanField(default=False, verbose_name='mollusc')), + ('groundnut', models.BooleanField(default=False, verbose_name='groundnut')), + ('sesame', models.BooleanField(default=False, verbose_name='sesame')), + ('alcohol', models.BooleanField(default=False, verbose_name='alcohol')), + ], + options={ + 'verbose_name': 'Allergen', + 'verbose_name_plural': 'Allergens', + }, + ), + migrations.CreateModel( + name='Basic_food', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='name')), + ('is_DLC', models.BooleanField(default=False, verbose_name='is DLC')), + ('is_DDM', models.BooleanField(default=False, verbose_name='is DDM')), + ('expiry_date', models.DateTimeField(blank=True, default=django.utils.timezone.now, verbose_name='expiry date')), + ('label', models.ImageField(default='pic/default.png', max_length=255, upload_to='label/', verbose_name='food label')), + ('was_eaten', models.BooleanField(default=False, verbose_name='was eaten')), + ('allergen', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='food.Allergen', verbose_name='allergen')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='member.Club', verbose_name='owner')), + ], + options={ + 'verbose_name': 'Basic food', + 'verbose_name_plural': 'Basic foods', + }, + ), + migrations.CreateModel( + name='QR_code', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('qr_code_number', models.PositiveIntegerField(verbose_name='QR-code number')), + ], + options={ + 'verbose_name': 'QR-code', + 'verbose_name_plural': 'QR-codes', + }, + ), + migrations.CreateModel( + name='Transformed_food', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='name')), + ('creation_date', models.DateTimeField(verbose_name='creation date')), + ('expiry_date', models.DateTimeField(verbose_name='expiry date')), + ('is_active', models.BooleanField(default=True, verbose_name='is active')), + ('was_eaten', models.BooleanField(default=False, verbose_name='was eaten')), + ('allergen', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='food.Allergen', verbose_name='allergen')), + ('basic_ingredient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='food.Basic_food', verbose_name='basic ingredient')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='member.Club', verbose_name='owner')), + ('qr_code', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='food.QR_code', verbose_name='QR code')), + ('transformed_ingredient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='food.Transformed_food', verbose_name='transformed ingredient')), + ], + options={ + 'verbose_name': 'Transformed food', + 'verbose_name_plural': 'Transformed foods', + }, + ), + migrations.AddField( + model_name='basic_food', + name='qr_code', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='food.QR_code', verbose_name='QR code'), + ), + ] diff --git a/apps/food/migrations/__init__.py b/apps/food/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/food/models.py b/apps/food/models.py new file mode 100644 index 00000000..acaa43f8 --- /dev/null +++ b/apps/food/models.py @@ -0,0 +1,257 @@ +# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + +from datetime import date + +from django.conf import settings +from django.contrib.auth.models import User +from django.core.exceptions import ValidationError +from django.core.validators import MinValueValidator +from django.db import models +from django.db.models import Q +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ +from member.models import Club + + +class QR_code(models.Model): + """ + An QR_code model + """ + qr_code_number = models.PositiveIntegerField( + verbose_name=_("QR-code number"), + ) + + class Meta: + verbose_name = _("QR-code") + verbose_name_plural = _("QR-codes") + + def __str__(self): + return _("QR-code number {qr_code_number}").format(qr_code_number=self.qr_code_number) + +class Allergen(models.Model): + """ + A list of allergen and alimentary restrictions + """ + + gluten = models.BooleanField( + default = False, + verbose_name = _('gluten'), + ) + + nut = models.BooleanField( + default = False, + verbose_name = _('nut'), + ) + + crustecean = models.BooleanField( + default = False, + verbose_name = _('crustacean'), + ) + + celery = models.BooleanField( + default = False, + verbose_name = _('celery'), + ) + + egg = models.BooleanField( + default = False, + verbose_name = _('egg'), + ) + + mustard = models.BooleanField( + default = False, + verbose_name = _('mustard'), + ) + + fish = models.BooleanField( + default = False, + verbose_name = _('fish'), + ) + + soy = models.BooleanField( + default = False, + verbose_name = _('soy'), + ) + + milk = models.BooleanField( + default = False, + verbose_name = _('milk'), + ) + + sulphite = models.BooleanField( + default = False, + verbose_name = _('sulphite'), + ) + + lupine = models.BooleanField( + default = False, + verbose_name = _('lupine'), + ) + + mollusc = models.BooleanField( + default = False, + verbose_name = _('mollusc'), + ) + + groundnut = models.BooleanField( + default = False, + verbose_name = _('groundnut'), + ) + + sesame = models.BooleanField( + default = False, + verbose_name = _('sesame'), + ) + + alcohol = models.BooleanField( + default = False, + verbose_name = _('alcohol'), + ) + + class Meta: + verbose_name = _('Allergen') + verbose_name_plural = _('Allergens') + + def __str__(self): + return _('Allergens of #{id}').format(id=self.id) + + +class Basic_food(models.Model): + """ + Food which has been directly buy on supermarket + """ + name = models.CharField( + verbose_name=_('name'), + max_length=255, + ) + + is_DLC = models.BooleanField( + verbose_name=_("is DLC"), + default=False, + ) + + is_DDM = models.BooleanField( + verbose_name=_("is DDM"), + default=False, + ) + + expiry_date = models.DateTimeField( + verbose_name=_('expiry date'), + default=timezone.now, + blank=True, + ) + + owner = models.ForeignKey( + Club, + on_delete=models.PROTECT, + related_name= '+', + verbose_name=_('owner'), + ) + + label = models.ImageField( + verbose_name=_('food label'), + max_length=255, + blank=False, + null=False, + upload_to='label/', + default= 'pic/default.png', + ) + + qr_code = models.ForeignKey( + QR_code, + on_delete=models.PROTECT, + related_name= '+', + verbose_name=_('QR code'), + ) + + was_eaten = models.BooleanField( + verbose_name=_('was eaten'), + default = False, + ) + + allergen = models.ForeignKey( + Allergen, + on_delete = models.PROTECT, + related_name = '+', + verbose_name = _('allergen'), + ) + + class Meta: + verbose_name=_('Basic food') + verbose_name_plural=_('Basic foods') + + def __str__(self): + return self.name + +class Transformed_food(models.Model): + """ + Transformed food are a mix between basic food and meal + """ + name = models.CharField( + max_length = 255, + verbose_name =_('name'), + ) + + creation_date = models.DateTimeField( + verbose_name =_('creation date'), + ) + + expiry_date = models.DateTimeField( + verbose_name =_('expiry date'), + ) + + owner = models.ForeignKey( + Club, + on_delete = models.PROTECT, + related_name = '+', + verbose_name =_('owner'), + ) + + transformed_ingredient = models.ForeignKey( + "self", + on_delete = models.CASCADE, + related_name = '+', + verbose_name = _('transformed ingredient'), + ) + + basic_ingredient = models.ForeignKey( + Basic_food, + on_delete = models.CASCADE, + related_name = '+', + verbose_name = _('basic ingredient'), + ) + + + is_active = models.BooleanField( + default = True, + verbose_name = _('is active'), + ) + + qr_code = models.ForeignKey( + QR_code, + on_delete = models.CASCADE, + related_name = '+', + verbose_name = _('QR code'), + ) + + was_eaten = models.BooleanField( + default = False, + verbose_name = _('was eaten'), + ) + + allergen = models.ForeignKey( + Allergen, + on_delete = models.PROTECT, + related_name= '+', + verbose_name = _('allergen'), + ) + + class Meta: + verbose_name = _('Transformed food') + verbose_name_plural = _('Transformed foods') + + def __str__(self): + return self.name + + diff --git a/apps/food/tests.py b/apps/food/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/apps/food/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/food/views.py b/apps/food/views.py new file mode 100644 index 00000000..91ea44a2 --- /dev/null +++ b/apps/food/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index 74fed818..93ae0afd 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -77,6 +77,7 @@ INSTALLED_APPS = [ 'scripts', 'treasury', 'wei', + 'food', ] MIDDLEWARE = [ From 4e6ec16e949231fd36b341b4bf6bc6cdef9ea31e Mon Sep 17 00:00:00 2001 From: quark Date: Fri, 17 May 2024 21:33:30 +0200 Subject: [PATCH 2/3] Rajout de la pseudo-doc --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 98fe3713..1f47efd3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# Traçabilité de la bouffe +doc provisoire ici : https://pad.crans.org/p/tracabilite +et ici : https://pad.crans.org/p/noteBouffe + # NoteKfet 2020 [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.txt) From c9980b0bd13ed97e8dae6180fe64a940c98ad939 Mon Sep 17 00:00:00 2001 From: quark Date: Tue, 21 May 2024 11:21:13 +0200 Subject: [PATCH 3/3] =?UTF-8?q?cr=C3=A9ation=20de=20l'interface=20admin=20?= =?UTF-8?q?temporaire?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/food/admin.py | 28 ++++++++++++++++++- .../migrations/0002_auto_20240521_1103.py | 19 +++++++++++++ .../migrations/0003_auto_20240521_1110.py | 19 +++++++++++++ apps/food/models.py | 2 ++ apps/food/urls.py | 7 +++++ apps/food/views.py | 4 ++- note_kfet/urls.py | 1 + 7 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 apps/food/migrations/0002_auto_20240521_1103.py create mode 100644 apps/food/migrations/0003_auto_20240521_1110.py create mode 100644 apps/food/urls.py diff --git a/apps/food/admin.py b/apps/food/admin.py index 8c38f3f3..820036c3 100644 --- a/apps/food/admin.py +++ b/apps/food/admin.py @@ -1,3 +1,29 @@ from django.contrib import admin +from note_kfet.admin import admin_site -# Register your models here. +from .models import QR_code, Basic_food, Transformed_food, Allergen + + +@admin.register(QR_code, site = admin_site) +class QR_codeAdmin(admin.ModelAdmin): + """ + TEMPORARY + """ + +@admin.register(Basic_food, site = admin_site) +class Basic_foodAdmin(admin.ModelAdmin): + """ + TEMPORARY + """ + +@admin.register(Transformed_food, site = admin_site) +class Transformed_foodAdmin(admin.ModelAdmin): + """ + TEMPORARY + """ + +@admin.register(Allergen, site = admin_site) +class AllergenAdmin(admin.ModelAdmin): + """ + TEMPORARY + """ diff --git a/apps/food/migrations/0002_auto_20240521_1103.py b/apps/food/migrations/0002_auto_20240521_1103.py new file mode 100644 index 00000000..6bdb8677 --- /dev/null +++ b/apps/food/migrations/0002_auto_20240521_1103.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.28 on 2024-05-21 09:03 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('food', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='transformed_food', + name='transformed_ingredient', + field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='food.Transformed_food', verbose_name='transformed ingredient'), + ), + ] diff --git a/apps/food/migrations/0003_auto_20240521_1110.py b/apps/food/migrations/0003_auto_20240521_1110.py new file mode 100644 index 00000000..9f92f534 --- /dev/null +++ b/apps/food/migrations/0003_auto_20240521_1110.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.28 on 2024-05-21 09:10 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('food', '0002_auto_20240521_1103'), + ] + + operations = [ + migrations.AlterField( + model_name='transformed_food', + name='transformed_ingredient', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='food.Transformed_food', verbose_name='transformed ingredient'), + ), + ] diff --git a/apps/food/models.py b/apps/food/models.py index acaa43f8..5347abc5 100644 --- a/apps/food/models.py +++ b/apps/food/models.py @@ -211,6 +211,8 @@ class Transformed_food(models.Model): transformed_ingredient = models.ForeignKey( "self", on_delete = models.CASCADE, + blank = True, + null = True, related_name = '+', verbose_name = _('transformed ingredient'), ) diff --git a/apps/food/urls.py b/apps/food/urls.py new file mode 100644 index 00000000..2fcca0db --- /dev/null +++ b/apps/food/urls.py @@ -0,0 +1,7 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path('', views.index, name='index') +] diff --git a/apps/food/views.py b/apps/food/views.py index 91ea44a2..c4cfa086 100644 --- a/apps/food/views.py +++ b/apps/food/views.py @@ -1,3 +1,5 @@ from django.shortcuts import render +from django.http import HttpResponse -# Create your views here. +def index(request): + return HttpResponse('test') diff --git a/note_kfet/urls.py b/note_kfet/urls.py index d222c239..01bec0ba 100644 --- a/note_kfet/urls.py +++ b/note_kfet/urls.py @@ -21,6 +21,7 @@ urlpatterns = [ path('activity/', include('activity.urls')), path('treasury/', include('treasury.urls')), path('wei/', include('wei.urls')), + path('food/',include('food.urls')), # Include Django Contrib and Core routers path('i18n/', include('django.conf.urls.i18n')),