feat: Add basic flow to add adoption notices
This commit is contained in:
parent
dda400f3ba
commit
8488768687
@ -12,4 +12,7 @@ debug=True
|
||||
backend=sqlite3
|
||||
name=notfellchen
|
||||
|
||||
[locations]
|
||||
media=./media
|
||||
|
||||
|
||||
|
@ -11,15 +11,6 @@ class Command(BaseCommand):
|
||||
|
||||
@staticmethod
|
||||
def populate_db():
|
||||
rat1 = baker.make_recipe(
|
||||
'fellchensammlung.rat'
|
||||
)
|
||||
rat2 = baker.make_recipe(
|
||||
'fellchensammlung.rat'
|
||||
)
|
||||
cat = baker.make_recipe(
|
||||
'fellchensammlung.cat'
|
||||
)
|
||||
rescue1 = baker.make_recipe(
|
||||
'fellchensammlung.rescue_org'
|
||||
)
|
||||
@ -27,9 +18,13 @@ class Command(BaseCommand):
|
||||
'fellchensammlung.rescue_org'
|
||||
)
|
||||
|
||||
baker.make(AdoptionNotice, name="Vermittung1", animals=[rat1, rat2], organization=rescue1)
|
||||
adoption1 = baker.make(AdoptionNotice, name="Vermittung1", organization=rescue1)
|
||||
|
||||
baker.make(AdoptionNotice, name="Vermittung2", animals=[cat], organization=rescue2)
|
||||
adoption2 = baker.make(AdoptionNotice, name="Vermittung2", organization=rescue2)
|
||||
|
||||
rat1 = baker.make(Animal, name="Rat1", adoption_notice=adoption1)
|
||||
rat2 = baker.make(Animal, name="Rat2", adoption_notice=adoption1)
|
||||
cat1 = baker.make(Animal, name="Cat1", adoption_notice=adoption1)
|
||||
|
||||
User.objects.create_user('test', password='foobar')
|
||||
User.objects.create_superuser(username="admin", password="admin")
|
||||
|
@ -1,73 +0,0 @@
|
||||
# Generated by Django 5.0.3 on 2024-03-17 22:05
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Location',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=200)),
|
||||
('postcode', models.CharField(max_length=200)),
|
||||
('country', models.CharField(choices=[('DE', 'Germany'), ('AT', 'Austria'), ('CH', 'Switzerland')], max_length=20)),
|
||||
('description', models.TextField(blank=True, null=True, verbose_name='Description')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Species',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(help_text='Enter a animal species', max_length=200, verbose_name='Name')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Species',
|
||||
'verbose_name_plural': 'Species',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RescueOrganization',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=200)),
|
||||
('trusted', models.BooleanField(default=False, verbose_name='Trusted')),
|
||||
('instagram', models.URLField(blank=True, null=True, verbose_name='Instagram profile')),
|
||||
('facebook', models.URLField(blank=True, null=True, verbose_name='Facebook profile')),
|
||||
('fediverse_profile', models.URLField(blank=True, null=True, verbose_name='Fediverse profile')),
|
||||
('website', models.URLField(blank=True, null=True, verbose_name='Website')),
|
||||
('location', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fellchensammlung.location')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='AdoptionNotice',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateField(verbose_name='Created at')),
|
||||
('searching_since', models.DateField(verbose_name='Searching for a home since')),
|
||||
('name', models.CharField(max_length=200)),
|
||||
('description', models.TextField(blank=True, null=True, verbose_name='Description')),
|
||||
('further_information', models.URLField(blank=True, null=True, verbose_name='Link to further information')),
|
||||
('group_only', models.BooleanField(default=False, verbose_name='Only group adoption')),
|
||||
('organization', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='fellchensammlung.rescueorganization', verbose_name='Organization')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Animal',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date_of_birth', models.DateField(blank=True, null=True, verbose_name='Date of birth')),
|
||||
('name', models.CharField(max_length=200)),
|
||||
('description', models.TextField(blank=True, null=True, verbose_name='Description')),
|
||||
('adoption_notice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='fellchensammlung.adoptionnotice')),
|
||||
('species', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fellchensammlung.species')),
|
||||
],
|
||||
),
|
||||
]
|
@ -1,22 +0,0 @@
|
||||
# Generated by Django 5.0.3 on 2024-03-18 09:33
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fellchensammlung', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='animal',
|
||||
name='adoption_notice',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='adoptionnotice',
|
||||
name='animals',
|
||||
field=models.ManyToManyField(to='fellchensammlung.animal'),
|
||||
),
|
||||
]
|
@ -1,24 +0,0 @@
|
||||
# Generated by Django 5.0.3 on 2024-03-18 13:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fellchensammlung', '0002_remove_animal_adoption_notice_adoptionnotice_animals'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='MarkdownContent',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=100)),
|
||||
('content', models.TextField()),
|
||||
],
|
||||
options={
|
||||
'verbose_name_plural': 'Markdown content',
|
||||
},
|
||||
),
|
||||
]
|
@ -1,36 +0,0 @@
|
||||
# Generated by Django 5.0.3 on 2024-03-18 16:08
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fellchensammlung', '0003_markdowncontent'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Image',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=200)),
|
||||
('image', models.ImageField(upload_to='images')),
|
||||
('alt_text', models.TextField(max_length=2000)),
|
||||
('uploaded_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='adoptionnotice',
|
||||
name='photos',
|
||||
field=models.ManyToManyField(blank=True, to='fellchensammlung.image'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='animal',
|
||||
name='photos',
|
||||
field=models.ManyToManyField(blank=True, to='fellchensammlung.image'),
|
||||
),
|
||||
]
|
@ -1,19 +0,0 @@
|
||||
# Generated by Django 5.0.3 on 2024-03-19 04:50
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fellchensammlung', '0004_image_adoptionnotice_photos_animal_photos'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='animal',
|
||||
name='sex',
|
||||
field=models.CharField(choices=[('M_N', 'male_neutered'), ('M', 'male'), ('F_N', 'female_neutered'), ('F', 'female')], default='female', max_length=20),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
@ -1,20 +0,0 @@
|
||||
# Generated by Django 5.0.3 on 2024-03-19 04:51
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fellchensammlung', '0005_animal_sex'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='animal',
|
||||
name='date_of_birth',
|
||||
field=models.DateField(default=datetime.datetime(2024, 3, 19, 4, 51, 44, 367516, tzinfo=datetime.timezone.utc), verbose_name='Date of birth'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
@ -63,6 +63,25 @@ class RescueOrganization(models.Model):
|
||||
website = models.URLField(null=True, blank=True, verbose_name=_('Website'))
|
||||
|
||||
|
||||
class AdoptionNotice(models.Model):
|
||||
def __str__(self):
|
||||
return f"{self.name}"
|
||||
|
||||
created_at = models.DateField(verbose_name=_('Created at'), default=datetime.now)
|
||||
searching_since = models.DateField(verbose_name=_('Searching for a home since'))
|
||||
name = models.CharField(max_length=200)
|
||||
description = models.TextField(null=True, blank=True, verbose_name=_('Description'))
|
||||
organization = models.ForeignKey(RescueOrganization, blank=True, null=True, on_delete=models.SET_NULL,
|
||||
verbose_name=_('Organization'))
|
||||
further_information = models.URLField(null=True, blank=True, verbose_name=_('Link to further information'))
|
||||
group_only = models.BooleanField(default=False, verbose_name=_('Only group adoption'))
|
||||
photos = models.ManyToManyField(Image, blank=True)
|
||||
|
||||
@property
|
||||
def animals_list(self):
|
||||
return self.animals.all()
|
||||
|
||||
|
||||
class Animal(models.Model):
|
||||
MALE_NEUTERED = "M_N"
|
||||
MALE = "M"
|
||||
@ -81,6 +100,7 @@ class Animal(models.Model):
|
||||
species = models.ForeignKey(Species, on_delete=models.PROTECT)
|
||||
photos = models.ManyToManyField(Image, blank=True)
|
||||
sex = models.CharField(max_length=20, choices=SEX_CHOICES, )
|
||||
adoption_notice = models.ForeignKey(AdoptionNotice, on_delete=models.CASCADE)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name}"
|
||||
@ -99,26 +119,6 @@ class Animal(models.Model):
|
||||
return reverse('animal-detail', args=[str(self.id)])
|
||||
|
||||
|
||||
class AdoptionNotice(models.Model):
|
||||
def __str__(self):
|
||||
return f"{self.name}"
|
||||
|
||||
created_at = models.DateField(verbose_name=_('Created at'))
|
||||
searching_since = models.DateField(verbose_name=_('Searching for a home since'))
|
||||
name = models.CharField(max_length=200)
|
||||
description = models.TextField(null=True, blank=True, verbose_name=_('Description'))
|
||||
organization = models.ForeignKey(RescueOrganization, blank=True, null=True, on_delete=models.SET_NULL,
|
||||
verbose_name=_('Organization'))
|
||||
further_information = models.URLField(null=True, blank=True, verbose_name=_('Link to further information'))
|
||||
group_only = models.BooleanField(default=False, verbose_name=_('Only group adoption'))
|
||||
animals = models.ManyToManyField(Animal)
|
||||
photos = models.ManyToManyField(Image, blank=True)
|
||||
|
||||
@property
|
||||
def animals_list(self):
|
||||
return self.animals.all()
|
||||
|
||||
|
||||
class MarkdownContent(models.Model):
|
||||
"""
|
||||
Base class to store markdown content
|
||||
|
@ -1,6 +0,0 @@
|
||||
{% extends "fellchensammlung/base_generic.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
Work in Progress: Vermitteln
|
||||
{% endblock %}
|
@ -0,0 +1,13 @@
|
||||
{% extends "fellchensammlung/base_generic.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Vermitteln</h1>
|
||||
Bitte mach dich zunächst mit unseren Regeln vertraut. Dann trage hier die ersten Informationen ein.
|
||||
Du bekommst in einem weiteren Schritt die Möglichkeit einzelne Tiere zu deiner Vermittlung hinzuzufügen und Fotos hochzuladen.
|
||||
<form method = "post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">Weiter</button>
|
||||
</form>
|
||||
{% endblock %}
|
@ -7,11 +7,17 @@ urlpatterns = [
|
||||
# ex: /animal/5/
|
||||
path("<int:animal_id>/", views.animal_detail, name="animal-detail"),
|
||||
# ex: /adoption_notice/7/
|
||||
path("<int:adoption_notice_id>/", views.adoption_notice_detail, name="adoption-notice-detail"),
|
||||
path("vermittlung/<int:adoption_notice_id>/", views.adoption_notice_detail, name="adoption-notice-detail"),
|
||||
|
||||
# ex: /search/
|
||||
path("suchen/", views.search, name="search"),
|
||||
# ex: /vermitteln/
|
||||
path("vermitteln/", views.add_adoption, name="add-adoption"),
|
||||
|
||||
# ex: vermitteln-tiere-hinzufügen/5
|
||||
path("vermitteln-tiere-hinzufügen/<int:adoption_notice_id>",
|
||||
views.add_animal_to_adoption,
|
||||
name="add-animal-to-adoption"),
|
||||
|
||||
path("ueber-uns/", views.about, name="about"),
|
||||
]
|
@ -1,8 +1,10 @@
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import render, redirect
|
||||
from django.http import HttpResponse
|
||||
from django.urls import reverse
|
||||
import markdown
|
||||
|
||||
from django.http import HttpResponse
|
||||
from fellchensammlung.models import AdoptionNotice, MarkdownContent, Animal
|
||||
from .forms import AdoptionNoticeForm, AnimalForm
|
||||
|
||||
|
||||
def index(request):
|
||||
@ -22,12 +24,42 @@ def animal_detail(request, animal_id):
|
||||
context = {"animal": animal}
|
||||
return render(request, 'fellchensammlung/detail_animal.html', context=context)
|
||||
|
||||
|
||||
def search(request):
|
||||
latest_adoption_list = AdoptionNotice.objects.order_by("-created_at")[:5]
|
||||
context = {"adoption_notices": latest_adoption_list}
|
||||
return render(request, 'fellchensammlung/search.html', context=context)
|
||||
|
||||
|
||||
def add_adoption(request):
|
||||
return render(request, 'fellchensammlung/add_adoption.html')
|
||||
if request.method == 'POST':
|
||||
form = AdoptionNoticeForm(request.POST, request.FILES)
|
||||
|
||||
if form.is_valid():
|
||||
instance = form.save()
|
||||
return redirect(reverse("add-animal-to-adoption", args=[instance.pk]))
|
||||
else:
|
||||
form = AdoptionNoticeForm()
|
||||
return render(request, 'fellchensammlung/form_add_adoption.html', {'form': form})
|
||||
|
||||
|
||||
def add_animal_to_adoption(request, adoption_notice_id):
|
||||
if request.method == 'POST':
|
||||
form = AnimalForm(request.POST, request.FILES)
|
||||
|
||||
if form.is_valid():
|
||||
form.cleaned_data["adoption_notice_id"] = adoption_notice_id
|
||||
instance = form.save(commit=False)
|
||||
instance.adoption_notice_id = adoption_notice_id
|
||||
instance.save()
|
||||
if "button_add_another_animal" in request.POST:
|
||||
return redirect(reverse("add-animal-to-adoption", args=[str(adoption_notice_id)]))
|
||||
else:
|
||||
return redirect(reverse("adoption-notice-detail", args=[str(adoption_notice_id)]))
|
||||
else:
|
||||
form = AnimalForm()
|
||||
return render(request, 'fellchensammlung/form_add_animal_to_adoption.html', {'form': form})
|
||||
|
||||
|
||||
def about(request):
|
||||
md = markdown.Markdown(extensions=["fenced_code"])
|
||||
@ -39,4 +71,3 @@ def about(request):
|
||||
"fellchensammlung/about.html",
|
||||
context=context
|
||||
)
|
||||
|
||||
|
@ -91,6 +91,9 @@ SEC_POLICY = config.get("security", "Policy",
|
||||
|
||||
""" LOCATIONS """
|
||||
STATIC_ROOT = config.get("locations", "static", fallback="/notfellchen/static")
|
||||
MEDIA_ROOT = config.get("locations", "media", fallback="/notfellchen/static")
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
|
||||
# see https://docs.djangoproject.com/en/3.2/ref/settings/#std-setting-ALLOWED_HOSTS
|
||||
ALLOWED_HOSTS = [config.get("notfellchen", "host", fallback='*')]
|
||||
|
@ -16,8 +16,15 @@ Including another URLconf
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
from django.conf import settings
|
||||
|
||||
from django.conf.urls.static import static
|
||||
|
||||
urlpatterns = [
|
||||
path("", include("fellchensammlung.urls")),
|
||||
path('admin/', admin.site.urls),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static(settings.MEDIA_URL,
|
||||
document_root=settings.MEDIA_ROOT)
|
||||
|
Loading…
Reference in New Issue
Block a user