feat: add LocationForm with cover_photo, location_detail view, update location_edit
This commit is contained in:
parent
2d7ca494bd
commit
e699ddb62d
5 changed files with 70 additions and 7 deletions
|
|
@ -71,3 +71,9 @@ class PruningLogForm(forms.ModelForm):
|
||||||
'pruned_on': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
|
'pruned_on': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
|
||||||
'notes': forms.Textarea(attrs={'rows': 2, 'class': 'form-control'}),
|
'notes': forms.Textarea(attrs={'rows': 2, 'class': 'form-control'}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class LocationForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Location
|
||||||
|
fields = ['name', 'cover_photo']
|
||||||
|
|
|
||||||
2
plants/templates/plants/location_detail.html
Normal file
2
plants/templates/plants/location_detail.html
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
{% extends "plants/base.html" %}
|
||||||
|
{% block content %}{{ location.name }}{% endblock %}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import pytest
|
import pytest
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from plants.models import Location
|
from plants.models import Location
|
||||||
|
from django.test import Client
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
|
|
@ -14,3 +16,36 @@ def test_location_cover_photo_field_exists():
|
||||||
loc.save()
|
loc.save()
|
||||||
loc.refresh_from_db()
|
loc.refresh_from_db()
|
||||||
assert loc.cover_photo.name.startswith('locations/')
|
assert loc.cover_photo.name.startswith('locations/')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def client():
|
||||||
|
return Client()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_location_detail_view_returns_200(client):
|
||||||
|
loc = Location.objects.create(name='My Terrace')
|
||||||
|
resp = client.get(reverse('location_detail', kwargs={'pk': loc.pk}))
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert b'My Terrace' in resp.content
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_location_edit_with_cover_photo(client):
|
||||||
|
import io
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
loc = Location.objects.create(name='Balcony')
|
||||||
|
buf = io.BytesIO()
|
||||||
|
Image.new('RGB', (1, 1), color=(0, 255, 0)).save(buf, format='JPEG')
|
||||||
|
buf.seek(0)
|
||||||
|
fake_img = SimpleUploadedFile('cover.jpg', buf.read(), content_type='image/jpeg')
|
||||||
|
resp = client.post(
|
||||||
|
reverse('location_edit', kwargs={'pk': loc.pk}),
|
||||||
|
{'name': 'Balcony Updated', 'cover_photo': fake_img},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 302
|
||||||
|
loc.refresh_from_db()
|
||||||
|
assert loc.name == 'Balcony Updated'
|
||||||
|
assert loc.cover_photo.name.startswith('locations/')
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ urlpatterns = [
|
||||||
path('photos/<int:photo_pk>/delete/', plants.delete_photo, name='delete_photo'),
|
path('photos/<int:photo_pk>/delete/', plants.delete_photo, name='delete_photo'),
|
||||||
path('pruning/', pruning.pruning_calendar, name='pruning_calendar'),
|
path('pruning/', pruning.pruning_calendar, name='pruning_calendar'),
|
||||||
path('locations/', locations.location_list, name='location_list'),
|
path('locations/', locations.location_list, name='location_list'),
|
||||||
|
path('locations/<int:pk>/', locations.location_detail, name='location_detail'),
|
||||||
path('locations/<int:pk>/edit/', locations.location_edit, name='location_edit'),
|
path('locations/<int:pk>/edit/', locations.location_edit, name='location_edit'),
|
||||||
path('locations/<int:pk>/delete/', locations.location_delete, name='location_delete'),
|
path('locations/<int:pk>/delete/', locations.location_delete, name='location_delete'),
|
||||||
path('species/search/', species.species_search, name='species_search'),
|
path('species/search/', species.species_search, name='species_search'),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ from django.shortcuts import render, get_object_or_404, redirect
|
||||||
from django.views.decorators.http import require_POST
|
from django.views.decorators.http import require_POST
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from plants.models import Location, Plant
|
from plants.models import Location, Plant
|
||||||
|
from plants.forms import LocationForm
|
||||||
|
|
||||||
|
|
||||||
def location_list(request):
|
def location_list(request):
|
||||||
|
|
@ -12,18 +13,36 @@ def location_list(request):
|
||||||
return redirect('location_list')
|
return redirect('location_list')
|
||||||
|
|
||||||
locations = Location.objects.annotate(plant_count=Count('plants'))
|
locations = Location.objects.annotate(plant_count=Count('plants'))
|
||||||
return render(request, 'plants/locations.html', {'locations': locations})
|
return render(request, 'plants/locations.html', {
|
||||||
|
'locations': locations,
|
||||||
|
'active_tab': 'garden',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def location_detail(request, pk):
|
||||||
|
location = get_object_or_404(Location, pk=pk)
|
||||||
|
plants = location.plants.select_related('species').prefetch_related('photos').all()
|
||||||
|
return render(request, 'plants/location_detail.html', {
|
||||||
|
'location': location,
|
||||||
|
'plants': plants,
|
||||||
|
'active_tab': 'garden',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def location_edit(request, pk):
|
def location_edit(request, pk):
|
||||||
location = get_object_or_404(Location, pk=pk)
|
location = get_object_or_404(Location, pk=pk)
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
name = request.POST.get('name', '').strip()
|
form = LocationForm(request.POST, request.FILES, instance=location)
|
||||||
if name:
|
if form.is_valid():
|
||||||
location.name = name
|
form.save()
|
||||||
location.save()
|
return redirect('location_list')
|
||||||
return redirect('location_list')
|
else:
|
||||||
return render(request, 'plants/location_edit.html', {'location': location})
|
form = LocationForm(instance=location)
|
||||||
|
return render(request, 'plants/location_edit.html', {
|
||||||
|
'location': location,
|
||||||
|
'form': form,
|
||||||
|
'active_tab': 'garden',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@require_POST
|
@require_POST
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue