Initial commit
This commit is contained in:
		
						commit
						aa48b6411f
					
				
					 17 changed files with 322 additions and 0 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | __pycache__ | ||||||
|  | db.sqlite3 | ||||||
|  | common/local_settings.py | ||||||
							
								
								
									
										0
									
								
								common/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								common/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										76
									
								
								common/settings.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								common/settings.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,76 @@ | ||||||
|  | """ | ||||||
|  | Django settings for recettes project. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import os | ||||||
|  | 
 | ||||||
|  | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | ||||||
|  | 
 | ||||||
|  | DEBUG = True | ||||||
|  | 
 | ||||||
|  | ALLOWED_HOSTS = [] | ||||||
|  | 
 | ||||||
|  | INSTALLED_APPS = [ | ||||||
|  |     'django.contrib.admin', | ||||||
|  |     'django.contrib.auth', | ||||||
|  |     'django.contrib.contenttypes', | ||||||
|  |     'django.contrib.sessions', | ||||||
|  |     'django.contrib.messages', | ||||||
|  |     'django.contrib.staticfiles', | ||||||
|  |     'recette', | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | MIDDLEWARE = [ | ||||||
|  |     'django.middleware.security.SecurityMiddleware', | ||||||
|  |     'django.contrib.sessions.middleware.SessionMiddleware', | ||||||
|  |     'django.middleware.common.CommonMiddleware', | ||||||
|  |     'django.middleware.csrf.CsrfViewMiddleware', | ||||||
|  |     'django.contrib.auth.middleware.AuthenticationMiddleware', | ||||||
|  |     'django.contrib.messages.middleware.MessageMiddleware', | ||||||
|  |     'django.middleware.clickjacking.XFrameOptionsMiddleware', | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | ROOT_URLCONF = 'common.urls' | ||||||
|  | 
 | ||||||
|  | TEMPLATES = [ | ||||||
|  |     { | ||||||
|  |         'BACKEND': 'django.template.backends.django.DjangoTemplates', | ||||||
|  |         'DIRS': [os.path.join(BASE_DIR, 'templates')], | ||||||
|  |         'APP_DIRS': True, | ||||||
|  |         'OPTIONS': { | ||||||
|  |             'context_processors': [ | ||||||
|  |                 'django.template.context_processors.debug', | ||||||
|  |                 'django.template.context_processors.request', | ||||||
|  |                 'django.contrib.auth.context_processors.auth', | ||||||
|  |                 'django.contrib.messages.context_processors.messages', | ||||||
|  |             ], | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | WSGI_APPLICATION = 'common.wsgi.application' | ||||||
|  | 
 | ||||||
|  | DATABASES = { | ||||||
|  |     'default': { | ||||||
|  |         'ENGINE': 'django.db.backends.sqlite3', | ||||||
|  |         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AUTH_PASSWORD_VALIDATORS = [] | ||||||
|  | 
 | ||||||
|  | LANGUAGE_CODE = 'fr' | ||||||
|  | 
 | ||||||
|  | TIME_ZONE = 'Europe/Zurich' | ||||||
|  | 
 | ||||||
|  | USE_I18N = True | ||||||
|  | 
 | ||||||
|  | USE_L10N = True | ||||||
|  | 
 | ||||||
|  | USE_TZ = True | ||||||
|  | 
 | ||||||
|  | STATIC_URL = '/static/' | ||||||
|  | MEDIA_URL = '/media/' | ||||||
|  | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') | ||||||
|  | 
 | ||||||
|  | from .local_settings import * | ||||||
							
								
								
									
										11
									
								
								common/urls.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								common/urls.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | from django.contrib import admin | ||||||
|  | from django.urls import path | ||||||
|  | 
 | ||||||
|  | from recette.views import home, recette | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | urlpatterns = [ | ||||||
|  |     path('admin/', admin.site.urls), | ||||||
|  |     path('', home, name='home'), | ||||||
|  |     path('recette/<int:pk>/', recette, name='recette'), | ||||||
|  | ] | ||||||
							
								
								
									
										16
									
								
								common/wsgi.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								common/wsgi.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | """ | ||||||
|  | WSGI config for recettes project. | ||||||
|  | 
 | ||||||
|  | It exposes the WSGI callable as a module-level variable named ``application``. | ||||||
|  | 
 | ||||||
|  | For more information on this file, see | ||||||
|  | https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import os | ||||||
|  | 
 | ||||||
|  | from django.core.wsgi import get_wsgi_application | ||||||
|  | 
 | ||||||
|  | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "recettes.settings") | ||||||
|  | 
 | ||||||
|  | application = get_wsgi_application() | ||||||
							
								
								
									
										15
									
								
								manage.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								manage.py
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | #!/usr/bin/env python | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     os.environ.setdefault("DJANGO_SETTINGS_MODULE", "common.settings") | ||||||
|  |     try: | ||||||
|  |         from django.core.management import execute_from_command_line | ||||||
|  |     except ImportError as exc: | ||||||
|  |         raise ImportError( | ||||||
|  |             "Couldn't import Django. Are you sure it's installed and " | ||||||
|  |             "available on your PYTHONPATH environment variable? Did you " | ||||||
|  |             "forget to activate a virtual environment?" | ||||||
|  |         ) from exc | ||||||
|  |     execute_from_command_line(sys.argv) | ||||||
							
								
								
									
										0
									
								
								recette/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								recette/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										25
									
								
								recette/admin.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								recette/admin.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | ||||||
|  | from django import forms | ||||||
|  | from django.contrib import admin | ||||||
|  | 
 | ||||||
|  | from .models import Composition, Ingredient, Recette, Unite | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class RecetteForm(forms.ModelForm): | ||||||
|  |     photo = forms.ImageField( | ||||||
|  |         label="Photo", | ||||||
|  |         widget=forms.ClearableFileInput(attrs={'capture': True, 'accept': "image/*"}), | ||||||
|  |         required=False | ||||||
|  |     ) | ||||||
|  |     class Meta: | ||||||
|  |         model = Recette | ||||||
|  |         fields = '__all__' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @admin.register(Recette) | ||||||
|  | class RecetteAdmin(admin.ModelAdmin): | ||||||
|  |     form = RecetteForm | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | admin.site.register(Composition) | ||||||
|  | admin.site.register(Ingredient) | ||||||
|  | admin.site.register(Unite) | ||||||
							
								
								
									
										5
									
								
								recette/forms.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								recette/forms.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | from django import forms | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class SearchForm(forms.Form): | ||||||
|  |     text = forms.CharField() | ||||||
							
								
								
									
										61
									
								
								recette/migrations/0001_initial.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								recette/migrations/0001_initial.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,61 @@ | ||||||
|  | from django.db import migrations, models | ||||||
|  | import django.db.models.deletion | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     initial = True | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.CreateModel( | ||||||
|  |             name='Composition', | ||||||
|  |             fields=[ | ||||||
|  |                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||||
|  |                 ('quantite', models.DecimalField(blank=True, decimal_places=3, max_digits=6, null=True)), | ||||||
|  |             ], | ||||||
|  |         ), | ||||||
|  |         migrations.CreateModel( | ||||||
|  |             name='Ingredient', | ||||||
|  |             fields=[ | ||||||
|  |                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||||
|  |                 ('nom', models.CharField(max_length=200, verbose_name='Nom')), | ||||||
|  |             ], | ||||||
|  |         ), | ||||||
|  |         migrations.CreateModel( | ||||||
|  |             name='Recette', | ||||||
|  |             fields=[ | ||||||
|  |                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||||
|  |                 ('nom', models.CharField(max_length=200, verbose_name='Nom')), | ||||||
|  |                 ('photo', models.ImageField(blank=True, upload_to='photos', verbose_name='Photo')), | ||||||
|  |                 ('nb_pers', models.IntegerField(default=4)), | ||||||
|  |                 ('prep', models.TextField(blank=True, verbose_name='Préparation')), | ||||||
|  |                 ('source', models.CharField(blank=True, max_length=200, verbose_name='Source')), | ||||||
|  |                 ('ingredients', models.ManyToManyField(blank=True, through='recette.Composition', to='recette.Ingredient')), | ||||||
|  |             ], | ||||||
|  |         ), | ||||||
|  |         migrations.CreateModel( | ||||||
|  |             name='Unite', | ||||||
|  |             fields=[ | ||||||
|  |                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||||
|  |                 ('nom', models.CharField(max_length=200, verbose_name='Unité')), | ||||||
|  |             ], | ||||||
|  |         ), | ||||||
|  |         migrations.AddField( | ||||||
|  |             model_name='composition', | ||||||
|  |             name='ingredient', | ||||||
|  |             field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='recette.Ingredient'), | ||||||
|  |         ), | ||||||
|  |         migrations.AddField( | ||||||
|  |             model_name='composition', | ||||||
|  |             name='recette', | ||||||
|  |             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='recette.Recette'), | ||||||
|  |         ), | ||||||
|  |         migrations.AddField( | ||||||
|  |             model_name='composition', | ||||||
|  |             name='unite', | ||||||
|  |             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='recette.Unite'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
							
								
								
									
										0
									
								
								recette/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								recette/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										38
									
								
								recette/models.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								recette/models.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | ||||||
|  | from django.db import models | ||||||
|  | from django.urls import reverse | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Ingredient(models.Model): | ||||||
|  |     nom = models.CharField("Nom", max_length=200) | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return self.nom | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Unite(models.Model): | ||||||
|  |     nom = models.CharField("Unité", max_length=200) | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return self.nom | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Recette(models.Model): | ||||||
|  |     nom = models.CharField("Nom", max_length=200) | ||||||
|  |     photo = models.ImageField("Photo", upload_to='photos', blank=True) | ||||||
|  |     nb_pers = models.IntegerField(default=4) | ||||||
|  |     prep = models.TextField("Préparation", blank=True) | ||||||
|  |     source = models.CharField("Source", max_length=200, blank=True) | ||||||
|  |     ingredients = models.ManyToManyField(Ingredient, through='Composition', blank=True) | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return self.nom | ||||||
|  | 
 | ||||||
|  |     def get_absolute_url(self): | ||||||
|  |         return reverse('recette', args=[self.pk]) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Composition(models.Model): | ||||||
|  |     recette = models.ForeignKey(Recette, on_delete=models.CASCADE) | ||||||
|  |     ingredient = models.ForeignKey(Ingredient, on_delete=models.PROTECT) | ||||||
|  |     quantite = models.DecimalField(max_digits=6, decimal_places=3, null=True, blank=True) | ||||||
|  |     unite = models.ForeignKey(Unite, null=True, blank=True, on_delete=models.PROTECT) | ||||||
							
								
								
									
										19
									
								
								recette/views.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								recette/views.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | ||||||
|  | from django.shortcuts import get_object_or_404, render | ||||||
|  | 
 | ||||||
|  | from .forms import SearchForm | ||||||
|  | from .models import Recette | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def home(request): | ||||||
|  |     form = SearchForm(request.POST or None) | ||||||
|  |     recettes = [] | ||||||
|  |     if request.method == 'POST': | ||||||
|  |         if form.is_valid(): | ||||||
|  |             recettes = Recette.objects.filter(nom__icontains=form.cleaned_data['text']) | ||||||
|  |          | ||||||
|  |     return render(request, 'index.html', context={'form': form, 'recettes': recettes}) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def recette(request, pk): | ||||||
|  |     recette = get_object_or_404(Recette, pk=pk) | ||||||
|  |     return render(request, 'recette.html', context={'recette': recette}) | ||||||
							
								
								
									
										1
									
								
								requirements.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								requirements.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | django>=2.0 | ||||||
							
								
								
									
										19
									
								
								templates/base.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								templates/base.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  | <head> | ||||||
|  |     <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> | ||||||
|  |     <title>Recettes {% block title %}page title{% endblock %}</title> | ||||||
|  |     <link rel="stylesheet" href="{{ STATIC_URL }}css/main.css"> | ||||||
|  |     {% block extrahead %} | ||||||
|  |     {% endblock %} | ||||||
|  | </head> | ||||||
|  | 
 | ||||||
|  | <body> | ||||||
|  |  <div id="content"> | ||||||
|  |  {% block content %} | ||||||
|  |  {% endblock %} | ||||||
|  |  </div> | ||||||
|  |  <hr> | ||||||
|  |  <div style="text-align: right;"><a href="{% url 'admin:index' %}">Gestion</a></div> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										16
									
								
								templates/index.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								templates/index.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | {% extends 'base.html' %} | ||||||
|  | 
 | ||||||
|  | {% block content %} | ||||||
|  | <h1>Recettes</h1> | ||||||
|  | 
 | ||||||
|  | <form method="POST">{% csrf_token %} | ||||||
|  |     {{ form.as_p }} | ||||||
|  |     <button>Rechercher</button> | ||||||
|  | </form> | ||||||
|  | 
 | ||||||
|  | <ul> | ||||||
|  | {% for recette in recettes %} | ||||||
|  |     <li><a href="{{ recette.get_absolute_url }}">{{ recette.nom }}</a></li> | ||||||
|  | {% endfor %} | ||||||
|  | </ul> | ||||||
|  | {% endblock %} | ||||||
							
								
								
									
										17
									
								
								templates/recette.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								templates/recette.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | {% extends 'base.html' %} | ||||||
|  | 
 | ||||||
|  | {% block content %} | ||||||
|  | <h1>{{ recette.nom }}</h1> | ||||||
|  | 
 | ||||||
|  | <div style="float:right;"><img src="{{ recette.photo }}"></div> | ||||||
|  | 
 | ||||||
|  | <div>{{ recette.preparation }}</div> | ||||||
|  | 
 | ||||||
|  | {% if recette.ingredients.count %} | ||||||
|  | <ul> | ||||||
|  |     {% for comp in recette.ingredients.all %} | ||||||
|  |     <li>{{ comp }}</li> | ||||||
|  |     {% endfor %} | ||||||
|  | </ul> | ||||||
|  | {% endif %} | ||||||
|  | {% endblock %} | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue