updated form validation in homepage, added optimization in db query, added customization in django admin panel
This commit is contained in:
parent
e1743be39b
commit
ef12610d6c
7 changed files with 133 additions and 27 deletions
|
@ -7,4 +7,24 @@ from .models import Album
|
||||||
class AlbumAdmin(admin.ModelAdmin):
|
class AlbumAdmin(admin.ModelAdmin):
|
||||||
list_display = ['id', 'image', 'is_verified']
|
list_display = ['id', 'image', 'is_verified']
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('General', {
|
||||||
|
'fields': ('object_type', 'description', 'image'),
|
||||||
|
}),
|
||||||
|
('User Info', {
|
||||||
|
'fields': (
|
||||||
|
('surname', 'first_name'),
|
||||||
|
('birth_date','postal_code'),
|
||||||
|
('address','town'),
|
||||||
|
('telephone','email'),
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
('Others', {
|
||||||
|
'fields': (
|
||||||
|
('target', 'is_agreed_terms_and_cond'),
|
||||||
|
'is_verified'
|
||||||
|
),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
admin.site.register(Album, AlbumAdmin)
|
admin.site.register(Album, AlbumAdmin)
|
||||||
|
|
19
album/migrations/0003_album_target.py
Normal file
19
album/migrations/0003_album_target.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 3.2 on 2022-09-27 22:51
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('album', '0002_auto_20220926_2135'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='album',
|
||||||
|
name='target',
|
||||||
|
field=models.CharField(choices=[('DONATE_TO_MUSEUM', 'Donate To Museum'), ('MAKE_IT_AVAILABLE_SOLELY', 'Make It Available Solely')], default='', max_length=100),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
|
@ -12,6 +12,10 @@ class Album(models.Model):
|
||||||
MOUNTAIN_STORY = 'MOUNTAIN_STORY'
|
MOUNTAIN_STORY = 'MOUNTAIN_STORY'
|
||||||
SPECIAL_KNOWLEDGE = 'SPECIAL_KNOWLEDGE'
|
SPECIAL_KNOWLEDGE = 'SPECIAL_KNOWLEDGE'
|
||||||
|
|
||||||
|
class TARGET_CHOICES(models.TextChoices):
|
||||||
|
DONATE_TO_MUSEUM = 'DONATE_TO_MUSEUM'
|
||||||
|
MAKE_IT_AVAILABLE_SOLELY = 'MAKE_IT_AVAILABLE_SOLELY'
|
||||||
|
|
||||||
object_type = models.CharField(max_length=40, choices=OBJECT_TYPE_CHOICES.choices)
|
object_type = models.CharField(max_length=40, choices=OBJECT_TYPE_CHOICES.choices)
|
||||||
description = models.TextField()
|
description = models.TextField()
|
||||||
image = models.ImageField()
|
image = models.ImageField()
|
||||||
|
@ -23,6 +27,7 @@ class Album(models.Model):
|
||||||
town = models.CharField(max_length=20)
|
town = models.CharField(max_length=20)
|
||||||
telephone = models.CharField(max_length=20)
|
telephone = models.CharField(max_length=20)
|
||||||
email = models.EmailField()
|
email = models.EmailField()
|
||||||
|
target = models.CharField(max_length=100, choices=TARGET_CHOICES.choices)
|
||||||
is_agreed_terms_and_cond = models.BooleanField()
|
is_agreed_terms_and_cond = models.BooleanField()
|
||||||
is_verified = models.BooleanField(default=False, blank=True)
|
is_verified = models.BooleanField(default=False, blank=True)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,21 @@
|
||||||
|
|
||||||
{% load humanize %}
|
{% load humanize %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block header %}
|
||||||
|
<style>
|
||||||
|
label[for="terms-and-condition-checkbox"] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
label[for="terms-and-condition-checkbox"] a {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{% endblock header %}
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
|
@ -67,7 +82,7 @@
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<section class="jumbotron">
|
<section class="jumbotron" style="background-image: url('https://cemhri.org/wp-content/uploads/2018/04/Home-Four-Banner-Background-Image.png') ">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
|
<a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
|
||||||
Wanna Contribute? click here..
|
Wanna Contribute? click here..
|
||||||
|
@ -81,92 +96,131 @@
|
||||||
<strong>I have ..</strong>
|
<strong>I have ..</strong>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios1" value="EQUIPMENT" checked>
|
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios1" value="EQUIPMENT" checked>
|
||||||
<label class="form-check-label" for="exampleRadios1">
|
<label class="form-check" for="exampleRadios1">
|
||||||
Equipment (helmet; rope; clothing; etc.)
|
Equipment (helmet; rope; clothing; etc.)
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios2" value="SUMMIT_PHOTOb">
|
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios2" value="SUMMIT_PHOTO">
|
||||||
<label class="form-check-label" for="exampleRadios2">
|
<label class="form-check" for="exampleRadios2">
|
||||||
Summit photo
|
Summit photo
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios3" value="CLIMBING_FILM">
|
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios3" value="CLIMBING_FILM">
|
||||||
<label class="form-check-label" for="exampleRadios3">
|
<label class="form-check" for="exampleRadios3">
|
||||||
Climbing film
|
Climbing film
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios4" value="MOUNTAIN_STORY">
|
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios4" value="MOUNTAIN_STORY">
|
||||||
<label class="form-check-label" for="exampleRadios4">
|
<label class="form-check" for="exampleRadios4">
|
||||||
Mountain story
|
Mountain story
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios5" value="SPECIAL_KNOWLEDGE">
|
<input class="form-check-input" type="radio" name="object_type" id="exampleRadios5" value="SPECIAL_KNOWLEDGE">
|
||||||
<label class="form-check-label" for="exampleRadios5">
|
<label class="form-check" for="exampleRadios5">
|
||||||
Special knowledge
|
Special knowledge
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="description"><strong>Description</strong></label>
|
<label for="description"><strong>Description</strong></label>
|
||||||
<textarea name="description" id="description" rows="5" class="form-control"></textarea>
|
<textarea name="description" id="description" rows="5" class="form-control" required></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="image"><strong>Image</strong></label>
|
<label for="image"><strong>Image</strong></label>
|
||||||
<div class="custom-file">
|
<div class="custom-file">
|
||||||
<input name="image" type="file" id="image" accept="image/png, image/gif, image/jpeg" >
|
<input name="image" type="file" id="image" accept="image/png, image/gif, image/jpeg" required>
|
||||||
<label id="image-label" class="custom-file-label" for="image">Choose an image</label>
|
<label id="image-label" class="custom-file-label" for="image">Choose an image</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="surname">Surname</label>
|
<label for="surname">Surname</label>
|
||||||
<input class="form-control" id="surname" aria-describedby="surname" placeholder="Enter Surname">
|
<input class="form-control" id="surname" name="surname" aria-describedby="surname" placeholder="Enter Surname" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="first_name">First Name</label>
|
<label for="first_name">First Name</label>
|
||||||
<input class="form-control" id="first_name" aria-describedby="first_name" placeholder="Enter First Name">
|
<input class="form-control" id="first_name" name="first_name" aria-describedby="first_name" placeholder="Enter First Name" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="birth_date">Date of Brith</label>
|
<label for="birth_date">Date of Brith</label>
|
||||||
<input type="date" class="form-control" id="birth_date" aria-describedby="first_name" placeholder="Enter surname">
|
<input type="date" class="form-control" id="birth_date" name="birth_date" aria-describedby="birth date" placeholder="Enter surname" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="address">Address</label>
|
<label for="address">Address</label>
|
||||||
<input class="form-control" id="address" aria-describedby="address" placeholder="Enter Address">
|
<input class="form-control" id="address" name="address" aria-describedby="address" placeholder="Enter Address" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="postal_code">Postal Code</label>
|
<label for="postal_code">Postal Code</label>
|
||||||
<input class="form-control" id="postal_code" aria-describedby="postal_code" placeholder="Enter Postal Code">
|
<input class="form-control" id="postal_code" name="postal_code" aria-describedby="postal_code" placeholder="Enter Postal Code" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="town">Town</label>
|
<label for="town">Town</label>
|
||||||
<input class="form-control" id="town" aria-describedby="town" placeholder="Enter Town Name">
|
<input class="form-control" id="town" name="town" aria-describedby="town" placeholder="Enter Town Name" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="telephone">Telephone</label>
|
<label for="telephone">Telephone</label>
|
||||||
<input class="form-control" id="telephone" aria-describedby="telephone" placeholder="Enter Telephone Number">
|
<input class="form-control" id="telephone" name="telephone" aria-describedby="telephone" placeholder="Enter Telephone Number" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="email">Email</label>
|
<label for="email">Email</label>
|
||||||
<input type="email" class="form-control" id="email" aria-describedby="email" placeholder="Enter email">
|
<input type="email" class="form-control" id="email" name="email" aria-describedby="email" placeholder="Enter email" required>
|
||||||
<small id="email" class="form-text text-muted">We'll never share your email with anyone else.</small>
|
<small id="email" class="form-text text-muted">We'll never share your email with anyone else.</small>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<strong>I would like to do the following with my object / my film / my story:</strong>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="target" id="exampleRadios7" value="DONATE_TO_MUSEUM" checked>
|
||||||
|
<label class="form-check-label" for="exampleRadios7">
|
||||||
|
Donate it to the collection of the Swiss Alpine Museum.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="target" id="exampleRadios8" value="MAKE_IT_AVAILABLE_SOLELY">
|
||||||
|
<label class="form-check-label" for="exampleRadios8">
|
||||||
|
Make it available solely for the Lost and Found Memories Office until october 2023.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" name="is_agreed_terms_and_cond" id="terms-and-condition-checkbox" value="True" required>
|
||||||
|
<label class="form-check-label" for="terms-and-condition-checkbox">
|
||||||
|
I have read and agree with the </label> <a href="#" data-toggle="modal" data-target=".bd-example-modal-lg">rules</a>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button class="btn btn-primary float-right" type="submit">Submit</button>
|
<button class="btn btn-primary float-right" type="submit">Submit</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<div class="modal data-bs-dismiss bd-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">X</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body p-3">
|
||||||
|
<h1 class="big-text" style="display: block;">Lost & Found Rules</h1>
|
||||||
|
<p data-block-key="p4tu6"></p><h4 data-block-key="c4plv">Rule 1: You’re the focus of attention in the Lost and Found Memories Office</h4><p data-block-key="a394e">We’re interested in what women have experienced in the mountains over the last fifty years. Anyone who would like to show a personal object in the museum and is prepared to tell their personal experiences or the history of mountaineering, climbing women can take part. There are no limits to the kind of objects as long as you are happy to exhibit your treasure in the Swiss Alpine Museum for two years.</p><h4 data-block-key="6oq5m">Rule 2: A formal start to our relationship – by filling out a form.</h4><p data-block-key="b07ki">If you want to join in, just fill out the form. Just give a short description of your personal objects that belong in a museum – and the memories you associate with them. We’ll look over your suggestion and get in touch with you to discuss the transfer details (contract for a loan or donation, handover date). As our space is limited, we do need to reserve the right to say no, unfortunately. And we hope you understand that we can’t accept any objects that are spontaneously brought along to the museum.</p><h4 data-block-key="cp7qk">Rule 3: You decide how you tell us your story.</h4><p data-block-key="adtg7">Every object in the exhibition receives a label. On the rear of the label there is space for your own story. We’d like it even more if you could pop round to the Lost and Found Memories Office from February 2020 onwards and tell us your tale in our video box. As soon as your object goes on show, we’ll let you know.</p><h4 data-block-key="78em">Rule 4: We decide together how long your object remains in the museum.</h4><p data-block-key="75fvd">You have two options: either you loan us the object for the duration of the Lost and Found Memories Office and pick it up again afterwards, or you donate it to the Swiss Alpine Museum and the item becomes part of our collection. We do need to reserve the right to decline a donation because of the type, size, or condition of the object.</p><h4 data-block-key="8afcr">Rule 5: Your object should have no reservations about being touched.</h4><p data-block-key="729kc">Generally speaking, when an object in private ownership is transferred to a museum collection, it can only be handled with gloves and is displayed behind glass. But we’d like to do things a bit differently at the Lost and Found Memories Office: the objects there can be touched. If your object needs special protection, you should let us know.</p><h4 data-block-key="a4n56">Rule 6: You won’t receive any unwelcome post.</h4><p data-block-key="165u5">Your personal details will be used exclusively for communication between the lender and the collection. If you want to receive the most up-to-date information about our other exciting projects, subscribe to our BergPost newsletter.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django.core import exceptions
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import (HttpResponse, HttpResponseBadRequest,
|
||||||
|
HttpResponseRedirect)
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.views.generic import CreateView, TemplateView
|
from django.views.generic import CreateView, TemplateView
|
||||||
|
|
||||||
from .models import Album
|
|
||||||
from .forms import AlbumForm
|
from .forms import AlbumForm
|
||||||
|
from .models import Album
|
||||||
from .serializers import AlbumCreateUpdateSerializer
|
from .serializers import AlbumCreateUpdateSerializer
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
@ -20,15 +22,24 @@ class HomePageView(TemplateView):
|
||||||
# NOTE: This will be used to update the active window in navbar
|
# NOTE: This will be used to update the active window in navbar
|
||||||
context.update({
|
context.update({
|
||||||
'contact_us_create': 'active',
|
'contact_us_create': 'active',
|
||||||
'albums': Album.objects.all()
|
'albums': Album.objects.filter(is_verified=True).only('id', 'image', 'is_verified')
|
||||||
})
|
})
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs) -> HttpResponse:
|
def post(self, request, *args, **kwargs) -> HttpResponse:
|
||||||
|
print(request.POST.get('surname'))
|
||||||
form = AlbumForm(request.POST, request.FILES)
|
form = AlbumForm(request.POST, request.FILES)
|
||||||
|
# print(form.__dict__)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
print(form)
|
# print('opno')
|
||||||
|
instance = form.save()
|
||||||
|
messages.success(self.request, 'Image uploaded successfully.')
|
||||||
|
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
else:
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
# raise exceptions.ValidationError(form.errors)
|
||||||
return
|
return
|
||||||
data = {'image': request.FILES.get('image')}
|
data = {'image': request.FILES.get('image')}
|
||||||
|
|
||||||
|
|
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
|
@ -22,9 +22,9 @@
|
||||||
<link href="{% static 'album/css/album.css' %}" rel="stylesheet">
|
<link href="{% static 'album/css/album.css' %}" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
{% block head %}
|
{% block header %}
|
||||||
|
|
||||||
{% endblock head %}
|
{% endblock header %}
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -44,9 +44,6 @@
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Bootstrap core JavaScript
|
<!-- Bootstrap core JavaScript
|
||||||
================================================== -->
|
================================================== -->
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
|
|
Loading…
Reference in a new issue