Update all

This commit is contained in:
Krzysztof 2021-02-06 12:31:59 +01:00
parent 7de2d58b80
commit 0251e4deb7
107 changed files with 445421 additions and 337 deletions

View File

@ -10,23 +10,17 @@ class OfferCreateForm(forms.ModelForm):
price = forms.DecimalField(min_value=0.01,max_digits=10, decimal_places=2)
class Meta:
model = Offer
fields = ('title','category','price','DMC','Places_to_sleep','cooker','fridge', 'microwave', 'Webasto', 'auto_temp_control', 'water_level_indicator', 'battery_level', 'photovoltaic_panels', 'gearbox', 'tempomat')
fields = ('title','category','price','description','DMC','Places_to_sleep','cooker','fridge', 'microwave', 'Webasto', 'auto_temp_control', 'water_level_indicator', 'battery_level', 'photovoltaic_panels', 'gearbox', 'tempomat')
class OfferImageCreateForm(forms.ModelForm):
image = forms.ImageField()
image = forms.ImageField(required = True)
main_image = forms.BooleanField(initial=False, required=False)
class Meta:
model = Image_offer
fields = ('image','main_image')
class BaseOfferImageFormSet(BaseFormSet):
def clean(self):
if any(self.errors):
return
count = 0
for form in self.forms:
if form.cleaned_data['main_image']:
count += 1
if count > 1:
raise forms.ValidationError(_("Mozna ustawić tylko jedno zdjecie jako miniaturka."))
pass
OfferImageFormSet = formset_factory(OfferImageCreateForm,formset = BaseOfferImageFormSet)

View File

@ -1,4 +1,4 @@
# Generated by Django 3.1.3 on 2021-01-12 17:44
# Generated by Django 3.1.3 on 2021-02-06 00:07
import camper.models
from django.conf import settings
@ -15,12 +15,6 @@ class Migration(migrations.Migration):
]
operations = [
migrations.CreateModel(
name='AlbumImage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
),
migrations.CreateModel(
name='Offer_Category',
fields=[
@ -40,6 +34,7 @@ class Migration(migrations.Migration):
('status', models.CharField(choices=[('Active', 'Active offer'), ('Inactive', 'Inactive offer'), ('Verification', 'Waiting for verication'), ('Blocked', 'Blocked Offer')], default='Inactive', max_length=32)),
('title', models.CharField(default='Tytuł oferty', max_length=50, verbose_name='Title')),
('slug', models.SlugField(default='', editable=False, max_length=70, unique=True)),
('description', models.TextField(default='', max_length=1000)),
('price', models.DecimalField(decimal_places=2, max_digits=10)),
('DMC', models.CharField(choices=[('B', 'Do 3.5 tony.'), ('C', 'Między 3.5 a 7.5 tony'), ('C1', 'Powyzej 7.5 tony')], default='B', max_length=32)),
('Places_to_sleep', models.IntegerField(default=2)),
@ -53,7 +48,6 @@ class Migration(migrations.Migration):
('photovoltaic_panels', models.BooleanField(default=False)),
('gearbox', models.CharField(choices=[('Manual', 'Skrzynia manualna'), ('Automat', 'Skrzynia automatyczna')], default='Manual', max_length=32)),
('tempomat', models.BooleanField(default=False)),
('album', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='album', to='camper.albumimage', verbose_name='')),
('category', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='camper.offer_category')),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
@ -66,7 +60,7 @@ class Migration(migrations.Migration):
name='Image_offer',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('image', models.ImageField(blank=True, null=True, upload_to=camper.models._upload_path)),
('image', models.ImageField(upload_to=camper.models._upload_path)),
('main_image', models.BooleanField(default=False)),
('offer', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, related_name='images', to='camper.offer', verbose_name='')),
],

View File

@ -1,20 +0,0 @@
# Generated by Django 3.1.3 on 2021-01-12 17:48
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('camper', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='offer',
name='album',
),
migrations.DeleteModel(
name='AlbumImage',
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 3.1.3 on 2021-01-24 16:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('camper', '0002_auto_20210112_1748'),
]
operations = [
migrations.AddField(
model_name='offer',
name='description',
field=models.TextField(default='', max_length=1000),
),
]

View File

@ -85,7 +85,7 @@ class Offer(models.Model):
return super(Offer, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('detail_offer_page', kwargs = {'slug': self.slug })
return reverse('offer_detail', kwargs = {'slug': self.slug })
def _upload_path(instance,filename):

View File

@ -7,8 +7,10 @@ from django.conf.urls.static import static
urlpatterns = [
re_path('add-offer/', views.CreateOffer.as_view(), name='create_offer'),
#path('offer/<slug:slug>', views.OfferDetailView.as_view(), name = 'offer_detail_view'),
path('offer/<slug:slug>', views.OfferDetailView.as_view(), name = 'offer_detail'),
path('update-offer/<slug:slug>',views.EditOffer.as_view(), name = 'update-offer'),
path('offers/', views.OfferListView.as_view(), name = 'list_offers'),
#path('offer/<slug:slug>', views.OfferDetailView.as_view(), name = 'detail_offer_page'),
path('', views.Home.as_view(), name='homepage')

View File

@ -28,30 +28,23 @@ def check_user_is_owner(request):
else:
render (request,'upgrade-to-onwer.html')
#def check_offer_belong_to_user(request):
# if request.check_user_is_owner() == True:
# if offer.author == request.users.id:
# return True
# else:
# raise ValueError("To chyba nie twoje :)")
# if check_users_is_owner == True:
# Create your views here.
class CreateOffer(CreateView):
@method_decorator(login_required)
def get(self, request,*args,**kwargs):
form = OfferCreateForm()
formset = OfferImageFormSet()
context = {
'form': form,
'formset': formset,
}
#if check_user_is_owner(request) == True or request.Base_user.is_staff == True:
return render(request,'offer/add-offer.html', context)
if check_user_is_owner(request) == True or request.user.is_staff == True:
form = OfferCreateForm()
formset = OfferImageFormSet()
context = {
'form': form,
'formset': formset,
}
#if check_user_is_owner(request) == True or request.Base_user.is_staff == True:
return render(request,'offer/add-offer.html', context)
else:
messages.error(request, 'Nie masz uprawnień!')
return redirect('/') #Redirect to login / register page for owner
@method_decorator(login_required)
def post(self,request,*args,**kwargs):
@ -64,7 +57,6 @@ class CreateOffer(CreateView):
offer.created_by = request.user
offer.status = 'Verification'
offer.save()
for photo in formset:
try:
imageoffer = Image_offer(offer = offer,main_image = photo.cleaned_data['main_image'],image = photo.cleaned_data['image'])
@ -74,7 +66,6 @@ class CreateOffer(CreateView):
offer.save()
messages.error(request,'Dodaj zdjęcia aby przesłać ofertę do weryfikacji')
return redirect('/') #Redirect to offe-update-page or user's offers list
messages.success(request,'Oferta utworzona i przesłana do weryfikacji')
return redirect('/') #Redirect to offer page or user's offers list
else:
@ -91,8 +82,6 @@ class CreateOffer(CreateView):
class EditOffer(UpdateView):
def get(self,request,*args, **kwargs):
pass
def post(self,request,*args,**kwargs):
pass
model = Offer
template_name = 'offer/update-offer.html'
fields = ('title','category','price','description','DMC','Places_to_sleep','cooker','fridge', 'microwave', 'Webasto', 'auto_temp_control', 'water_level_indicator', 'battery_level', 'photovoltaic_panels', 'gearbox', 'tempomat')

View File

@ -2,28 +2,72 @@ from django.shortcuts import render,redirect, get_object_or_404
from django.views.generic import (
ListView,
DetailView,
View
View,
FormView,
CreateView,
)
from camper.models import Offer, Image_offer
from camper.models import Offer, Image_offer,Offer_Category
from django.http import Http404, HttpResponseRedirect
from django.core.paginator import Paginator ,EmptyPage, PageNotAnInteger
from reservation.forms import ReservationForm
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import FormMixin
from reservation.models import Reservation
class Home(View):
def get(self, request, *args, **kwargs):
return render(request, 'index.html')
context = {}
offers= Offer.objects.filter(status = 'Active').order_by('-date_added')[:2]
context['offers'] = offers
return render(request,'home.html', context=context)
################################################
class OfferDetailView(DetailView):
template_name = 'offer/offer-detail.html'
model = Offer
context_object_name = 'offer'
template_name = 'offer/offer-detail.html'
def get_context_data(self, *args, **kwargs):
context = super(OfferDetailView,self).get_context_data(*args, **kwargs)
context.update({
'form': ReservationForm(),
})
return context
@method_decorator(login_required)
def post(self,request,*args,**kwargs):
self.object = self.get_object(self.get_queryset())
form = ReservationForm(self.request.POST)
if form.is_valid():
reservation = form.save(commit = False)
reservation.user = request.user
reservation.offer = self.object
reservation.status = 'Confirmed'
reservation.save()
messages.success(request,'Twoja rezerwacja została potwierdzona.')
return redirect('/')
else:
context = self.get_context_data(**kwargs)
context.update({'form': ReservationForm()})
messages.error(request, 'Wprowadzone dane są nieprawidłowe.')
return render(request,'offer/offer-detail.html', context)
################################################
class OfferListView(ListView):
model = Offer
template_name = 'offer/offers.html'
context_object_name = 'active_offers_list'
paginate_by = 4
allow_empty_first_page = True
ordering = ['-date_added']
def get_queryset(self):

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
vagus/media/uploads/._default.png Executable file

Binary file not shown.

BIN
vagus/media/uploads/default.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

444938
vagus/mysite.log Executable file

File diff suppressed because it is too large Load Diff

View File

@ -2,10 +2,23 @@ from django.contrib import admin
from .models import Reservation
from .forms import ReservationForm
class ReservationAdmin(admin.ModelAdmin):
list_display = ('__str__','offer','status')
ordering = ['reservation_start_date']
group_by = ['offer','user']
class CustomReservation(admin.ModelAdmin):
admin.site.register(Reservation, ReservationAdmin)
model = Reservation
list_display = ('created_date','user','offer','reservation_start_date','reservation_end_date','reservation_cost')
fieldsets = (
(None, {'fields': ('user','offer','reservation_start_date','reservation_end_date','status','message_to_owner',)}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('user','offer','reservation_start_date','reservation_end_date','status',)}
),
)
ordering = ('offer','user')
search_fields = ('offer','user')
admin.site.register(Reservation, CustomReservation)

View File

@ -3,20 +3,24 @@ from .models import Reservation
from camper.models import Offer
from users.models import Base_User
from django.core.exceptions import ValidationError
from bootstrap_datepicker_plus import DatePickerInput
class ReservationForm(forms.ModelForm):
reservation_start_date = forms.DateField(required=True)
reservation_end_date = forms.DateField(required=True,)
reservation_start_date = forms.DateField(
widget=DatePickerInput(format='%m/%d/%Y')
)
reservation_end_date = forms.DateField(
widget=DatePickerInput(format='%m/%d/%Y')
)
class Meta:
model = Reservation
exclude = ('user',)
widget = {
'reservation_start_date': forms.DateInput(format =['%d/%m/%y']),
'reservation_end_date': forms.DateInput(format =['%d/%m/%y']),
}
exclude = ('user','offer','status','reservation_cost')
fields = ['reservation_start_date','reservation_end_date','message_to_owner']
class ReservationStatus(forms.ModelForm):
class Meta:
model = Reservation
fields = ['status']

View File

@ -1,4 +1,4 @@
# Generated by Django 3.1.3 on 2021-01-14 00:40
# Generated by Django 3.1.3 on 2021-02-06 09:49
from django.conf import settings
from django.db import migrations, models
@ -11,8 +11,8 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('camper', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('camper', '0002_auto_20210112_1748'),
]
operations = [
@ -20,11 +20,15 @@ class Migration(migrations.Migration):
name='Reservation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_date', models.DateTimeField(auto_now_add=True)),
('reservation_start_date', models.DateField(default=django.utils.timezone.now)),
('reservation_end_date', models.DateField()),
('reservation_cost', models.DecimalField(decimal_places=2, default=0, max_digits=12)),
('message_to_owner', models.TextField(blank=True, max_length=500, null=True)),
('status', models.CharField(choices=[('Confirmed', 'Rezerwacja potwierdzona'), ('Requsted', 'Oczekuję na potwierdzenie'), ('Cancelled', 'Anulowana'), ('In_progress', 'Trwająca rezerwacja')], max_length=50)),
('offer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camper.offer', verbose_name='')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='')),
('slug', models.SlugField(default='', editable=False, max_length=255)),
('offer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camper.offer', verbose_name='Offer')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User')),
],
),
]

View File

@ -1,33 +0,0 @@
# Generated by Django 3.1.3 on 2021-01-15 00:37
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('camper', '0002_auto_20210112_1748'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('reservation', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='reservation',
name='offer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camper.offer', verbose_name='Offer'),
),
migrations.AlterField(
model_name='reservation',
name='reservation_start_date',
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='reservation',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.3 on 2021-02-06 10:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('reservation', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='reservation',
name='id',
field=models.AutoField(primary_key=True, serialize=False),
),
]

View File

@ -1,19 +0,0 @@
# Generated by Django 3.1.3 on 2021-01-24 14:57
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('reservation', '0002_auto_20210115_0037'),
]
operations = [
migrations.AlterField(
model_name='reservation',
name='reservation_start_date',
field=models.DateField(default=django.utils.timezone.now),
),
]

View File

@ -6,37 +6,70 @@ from django.core.exceptions import ValidationError
from django.conf import settings
from django.core.exceptions import NON_FIELD_ERRORS
from django.db.models import Q
from django import forms
from django.contrib import messages
from django.template.defaultfilters import slugify
from django.urls import reverse
STATUS = (
('Confirmed',_('Rezerwacja potwierdzona')),
('Requsted',_('Oczekuję na potwierdzenie')),
('Cancelled',_('Anulowana')),
('In_progress',_('Trwająca rezerwacja')),
)
class Reservation(models.Model):
id = models.AutoField(primary_key= True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_("User"), on_delete=models.CASCADE)
offer = models.ForeignKey("camper.Offer", verbose_name=_("Offer"), on_delete=models.CASCADE)
created_date = models.DateTimeField(auto_now_add=True)
reservation_start_date = models.DateField(default = timezone.now,)
reservation_end_date = models.DateField()
reservation_cost = models.DecimalField(max_digits=12,default=0,decimal_places=2)
message_to_owner = models.TextField(max_length=500, blank = True, null = True)
status = models.CharField(choices = STATUS, max_length = 50)
slug = models.SlugField(max_length=255,editable = False, default='', unique = False)
def __str__(self):
return "%s (%s to %s)" % (self.user.email,
self.reservation_start_date.strftime(
"%Y/%m/%d"),
self.reservation_end_date.strftime(
"%Y/%m/%d"),)
"%Y/%m/%d"),)
@property
def get_total_cost(self):
diff_days = self.reservation_end_date - self.reservation_start_date
self.reservation_cost = diff_days.days * self.offer.price
return self.reservation_cost
def clean(self):
def clean(self,*args,**kwargs):
errors = {}
if self.reservation_end_date < self.reservation_start_date:
errors['reservation_end_date'] = "Data zakończenia wynajmu nie moze byc data wczesniejsza od daty rozpoczecia."
today_date = timezone.now().date()
if self.created_date != None:
if self.reservation_start_date < today_date:
errors['reservation_start_date'] = "Rezerwacja nie moze rozpoczynać sie w przeszłości"
if self.reservation_end_date < self.reservation_start_date:
errors['reservation_end_date'] = "Data zakończenia wynajmu nie moze byc data wczesniejsza / równa od daty rozpoczecia."
if self.reservation_end_date == self.reservation_start_date:
errors['reservation_end_date'] = "Wynajem nie moze kończyc sie w dniu rozpoczecia wynajmu."
if errors:
raise forms.ValidationError(errors)
filter_params = dict(reservation_end_date__lte=self.reservation_end_date, reservation_start_date__gte=self.reservation_start_date, offer = self.offer)
if Reservation.objects.filter(**filter_params).exists():
def get_absolute_url(self):
return reverse("reservation_detail", kwargs={"slug": self.slug})
def save(self,*args,**kwargs):
errors = {}
filter_params = dict(reservation_end_date__lte=self.reservation_end_date, reservation_start_date__gte=self.reservation_start_date,offer =self.offer)
if Reservation.objects.filter(**filter_params):
errors[NON_FIELD_ERRORS] = "Kamper w tym okresie jest juz zarezerwowany."
raise ValidationError(errors)
if errors:
raise forms.ValidationError(errors)
else:
self.slug = slugify(f'{self.offer.title}-{self.id}-/{self.reservation_start_date}-{self.reservation_end_date}')
return super(Reservation,self).save(*args,**kwargs)

View File

@ -7,28 +7,3 @@ from users.models import Base_User
# Create your tests here.
class ReservationCreate(TestCase):
def setUp(self):
testauthor = Base_User.objects.create(email ='test2@vagus.pl', password = '13test45')
testoffer = Offer.objects.create(title = 'tytul',created_by = testauthor,price = 23, category = Offer_Category.objects.get(name = 'CamperVan'))
def test_correct_date(self):
today= datetime.date.today()
ed = datetime.date(year=2021, month=1, day=20)
Reservation.objects.create(
user = Base_User.objects.get(email = 'test2@vagus.pl'),
offer = Offer.objects.get(id = 16),
reservation_start_date = today,
reservation_end_date = ed,
)
def test_incorret_date(self):
today = datetime.date.today()
ed = datetime.date(year = 2020, month=5, day = 15)
Reservation.objects.create(
user = Base_User.objects.get(email = 'test2@vagus.pl'),
offer = Offer.objects.get(id = 16),
reservation_start_date = today,
reservation_end_date = ed,
)

View File

@ -3,9 +3,10 @@ from django.urls import path
from django.conf.urls.static import static
from camper.models import Offer
from . import views
from django.contrib.auth.decorators import login_required
urlpatterns = [
path('offer/<slug:slug>', views.DetailOfferPage.as_view(), name = 'detail_offer_page'),
path('reservation-detail/<slug:slug>', login_required(views.Reservation_Detail.as_view()), name = 'reservation_detail'),
]

View File

@ -1,22 +1,12 @@
from django.shortcuts import render,get_object_or_404
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from .forms import ReservationForm
from camper.models import Offer, Image_offer
from django.views.generic import (
DetailView
DetailView,
UpdateView
)
from .models import Reservation
from .forms import ReservationStatus
class DetailOfferPage(DetailView):
model = Offer
template_name = 'offer/offer-detail.html'
def get_context_data(self, **kwargs):
context = super(DetailOfferPage, self).get_context_data(**kwargs)
context['form'] = ReservationForm
context['Image_offer'] = Image_offer.objects.filter(offer = self.object)
return context
@method_decorator(login_required)
def post(self,request,*args,**kwargs):
pass
class Reservation_Detail(UpdateView):
model = Reservation
template_name = 'reservation/reservation-detail.html'
form_class = ReservationStatus

View File

@ -20,8 +20,7 @@ body a:hover {
text-decoration: none;}
.container {
width: 1380px;
max-width: 100%;
max-width: 1380px;
margin: 0 auto;
}
@ -118,13 +117,6 @@ body a:hover {
font-weight: 600!important;
}
.header-nav-bar-avatar {
min-width: 36px;
max-height: 36px;
padding-left: 10px;
}
.header-nav-bar img {
width: 36px;
border-radius: 50%;
@ -157,8 +149,8 @@ body a:hover {
.main-content {
padding-left: 20px;
padding-right: 20px;
padding-left: 10px;
padding-right: 10px;
}
/* OFFERS BOX */
@ -235,7 +227,44 @@ body a:hover {
.offer-detail-row {
display: flex;
flex-direction: row;
}
.offer-detail-content {
min-width: 600px;
}
.offer-detail-status-info {
font-size: 2em;
font-weight: bold;
}
.offer-detail-title-text {
font-size: 1.8em;
}
.offer-detail-description {
margin-top: 25px;
}
.offer-detail-parameters {
margin-top: 25px;
}
.offer-detail-parameters li {
display: inline;
}
.offer-detail-price {
margin:15px;
font-size: 1.5em;
text-align: right;
}
.offer-reservation {
flex:40%;
min-width: 300px;
margin-top: 50px;
}
/* PROFILE */
.profile-wrapper {
@ -250,7 +279,6 @@ body a:hover {
}
.profile-wrapper-row-information {
flex:20%;
background-color: crimson;
}
.profile-wrapper-row-content {
flex:70%;
@ -295,3 +323,60 @@ body a:hover {
}
/* HOME PAGE */
.home-header{
background:
linear-gradient(
rgba(0, 0, 0, 0.5),
rgba(0, 0, 0, 0.5)
),
url(/media/ian-usher-Af1OMQpuN14-unsplash.jpg);
background-size: cover;
height: 70vh;
}
.home-header-title {
position: absolute;
font-size: 3em;
top: 45%;
left: 35%;
transform: translate(-50%, -50%);
color: white;
text-align: center;
}
.home-header-button {
border: 1px solid black;
border-radius: 25px;
height: 40px;
width: 300px
}
.home-header-button p {
font-size: 0.5em;
}
.home-row{
display: flex;
justify-content: space-between;
background-color: black;
color: white;
}
.home-grid-offer {
flex:2;
text-align: center;
padding: 50px 25px 50px 25px;
}
.home-grid-offer a, a:hover {
color:white;
}
.home-grid-offer img {
width: 450px;
}
.home-footer-copyright {
width: 100%;
background-color: black;
color: white;
text-align: right;
padding: 50px 10px 1px 10px;
}
.home-footer-copyright p {
font-size: 1em;
}

View File

@ -1,42 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<link rel="stylesheet" href = 'style.css'>
<link href = "https://fonts.googleapis.com/css?family=Dosis" rel='stylesheet'>
<link href = "https://fonts.googleapis.com/css?family=Poppins" rel='stylesheet'>
</head>
<body>
<div class='header-smart-baner'> <!-- TOP HEADER SMART BANER-->
<div class='header-smart-baner-text'> Lubisz ciasteczka? Mamy ich naprawdę duzo.</div>
</div> <!-- TOP HEADER SMART BANER END-->
<div class='header'>
<div class='container'>
<div class='header-inner'>
<div class='header-logo'> <a href='#'> vagus </a> </div>
<div class='header-nav'>
<a href='#'>KAMPERY </a>
<a href='#'>O NAS </a>
<a href='#'>FAQ</a>
<a href='#'>KONTAKT </a>
<div class='header-nav-bar'>
<div class='header-nav-bar-container'>
<div class='header-nav-bar-menu-mobile'>
<div class='header-nav-bar-menu-mobile-icon'></div>
<div class='header-nav-bar-menu-mobile-icon'></div>
<div class='header-nav-bar-menu-mobile-icon'></div>
</div>
<div class='header-nav-bar-text'> Witaj, Krzysztof</div>
<div class='header-nav-bar-avatar'> <img src='photo.jpg'> </div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

33
vagus/template/home.html Executable file
View File

@ -0,0 +1,33 @@
{% extends 'index.html' %}
{% load static %}
{% block content %}
<div class='container'>
<div class='home-wrapper'>
<section class='home-header'>
<div class="home-header-title">
<h1>Stress is caused by</h1>
<p>not camping enough!</p>
<a href = "{{ request.scheme }}://{{ request.META.HTTP_HOST }}/offers"><button class='home-header-button'> <p>Zarezerwuj swój kamper</p> </button> </a>
</div>
</section>
<div class='home-row'>
{% for offer in offers%}
<div class='home-grid-offer'>
<a href ="{{ offer.get_absolute_url}}"> <h4> {{ offer.title}} </h4></a>
{% for photo in offer.images.all %}
{% if photo.main_image == True%}
<img src="{{ photo.image.url }}">
{% endif %}
{% endfor %}
</div>
{% endfor %}
</div>
<div class='home-footer-copyright'>
<p> Copyright by Krzysztof Bonecki 2021 </p>
</div>
</div>
</div>
{% endblock %}

View File

@ -14,7 +14,7 @@
</head>
<body>
<div class='header-smart-baner'> <!-- TOP HEADER SMART BANER-->
<div class='header-smart-baner-text'> Lubisz ciasteczka? Mamy ich naprawdę duzo.</div>
<div class='header-smart-baner-text'> Lorem Ipsum is simply dummy text of the print...</div>
</div> <!-- TOP HEADER SMART BANER END-->
<div class='header'>
<div class='container'>
@ -22,30 +22,28 @@
<div class='header-logo'> <a href='{{ request.scheme }}://{{ request.META.HTTP_HOST }}/'> vagus </a> </div>
<div class='header-nav'>
<a href='{{ request.scheme }}://{{ request.META.HTTP_HOST }}/offers'>KAMPERY </a>
<a href='{{ request.scheme }}://{{ request.META.HTTP_HOST }}/add-offer'>DODAJ OFERTĘ </a>
<div class='header-nav-bar'>
<div class='header-nav-bar-container'>
<div class='header-nav-bar-text'>
{% if user.is_authenticated %}
{% if user.status != 'Moderator' %}
<a class='link' href='{{ request.scheme }}://{{ request.META.HTTP_HOST }}/profile'> Witaj, {{ user.first_name }} </a>
{% else %}
<a href='{{ request.scheme }}://{{ request.META.HTTP_HOST }}/profile'>Witaj, Adminie </a>
{% endif %}
{% else %}
<a href='{{ request.scheme }}://{{ request.META.HTTP_HOST }}/login'>Witaj, nieznajomy </a>
{% endif %}
</div>
<div class='header-nav-bar-avatar'>
{% if user.avatar %}
<img src={{ user.avatar.url }}>
<div class='header-nav-bar-container'>
<div class='header-nav-bar-text'>
{% if user.is_authenticated %}
{% if user.status != 'Moderator' %}
<a class='link' href='{{ request.scheme }}://{{ request.META.HTTP_HOST }}/profile'> Witaj, {{ user.first_name }} </a>
{% else %}
<a href='{{ request.scheme }}://{{ request.META.HTTP_HOST }}/profile'>Witaj, Adminie </a>
{% endif %}
{% else %}
<img src='/media/avatars/default.png'>
{%endif%}
<a href='{{ request.scheme }}://{{ request.META.HTTP_HOST }}/login'>Witaj, nieznajomy </a>
{% endif %}
</div>
<div class='header-nav-bar-avatar'>
{% if user.avatar %}
<img src={{ user.avatar.url }}>
{% else %}
<img src='/media/avatars/default.png'>
{%endif%}
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -38,31 +38,30 @@
</div>
<div class='offer-detail-parameters'>
<ul>
<li> 'DMC' <b> {{offer.DMC}} </b> </li>
<li> 'Places_to_sleep' <b> {{offer.Places_to_sleep}} </b></li>
<li> 'cooker' <b> {{offer.cooker}} </b></li>
<li> 'fridge' <b> {{offer.fridge}} </b></li>
<li> 'microwave' <b> {{offer.microwave}} </b></li>
<li> 'Webasto' <b> {{offer.Webasto}} </b></li>
<li> 'auto_temp_control' <b> {{offer.auto_temp_control}} </b></li>
<li> 'water_level_indicator' <b> {{offer.water_level_indicator}} </b> </li>
<li> 'battery_level'<b> {{offer.battery_level}} </b> </li>
<li> 'photovoltaic_panels' <b> {{offer.photovoltaic_panels}} </b> </li>
<li> 'gearbox <b> {{offer.gearbox}} </b> </li>
<li> 'tempomat' <b> {{offer.tempomat}} </b> </li>
<ul class="list-group">
<li class="list-group-item"> 'DMC' <b> {{offer.DMC}} </b> </li>
<li class="list-group-item"> 'Places_to_sleep' <b> {{offer.Places_to_sleep}} </b></li>
<li class="list-group-item"> 'cooker' <b> {{offer.cooker}} </b></li>
<li class="list-group-item"> 'fridge' <b> {{offer.fridge}} </b></li>
<li class="list-group-item"> 'microwave' <b> {{offer.microwave}} </b></li>
<li class="list-group-item"> 'Webasto' <b> {{offer.Webasto}} </b></li>
<li class="list-group-item"> 'auto_temp_control' <b> {{offer.auto_temp_control}} </b></li>
<li class="list-group-item"> 'water_level_indicator' <b> {{offer.water_level_indicator}} </b> </li>
<li class="list-group-item"> 'battery_level'<b> {{offer.battery_level}} </b> </li>
<li class="list-group-item"> 'photovoltaic_panels' <b> {{offer.photovoltaic_panels}} </b> </li>
<li class="list-group-item"> 'gearbox <b> {{offer.gearbox}} </b> </li>
<li class="list-group-item"> 'tempomat' <b> {{offer.tempomat}} </b> </li>
</ul>
</div>
<div class ='offer-detail-price'> KOSZT: {{offer.price}} PLN / dzień</div>
</div>
</div>
<div class='offer-reservation'>
<form id="form-container" method="POST" class="reservation-form">
<h3> Zarezerwuj kamper </h3>
{% csrf_token %}
{{ form.media }}
{{form.as_p}}
<button style="background-color:black; color:white" class="btn btn-outline-info" type="submit">Wyślij zapytanie</button>
</form>
<div>

View File

@ -0,0 +1,11 @@
{% extends 'index.html' %}
{% load static %}
{% block content %}
<form method="post">{% csrf_token %}
{{ form.as_p }}
{{formset.as_p}}
<input type="submit" value="Update">
</form>
{% endblock %}

View File

@ -0,0 +1,30 @@
{% extends 'index.html' %}
{% load static %}
{% block content %}
<table class="table">
<thead>
<tr>
<th scope="col">Tytuł oferty</th>
<th scope="col">Data rezerwacji</th>
<th scope="col">Początek rezerwacji</th>
<th scope="col">Koniec rezerwacji</th>
<th scope ="col"> Koszt </th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<a href="{{ reservation.offer.get_absolute_url }}">{{ reservation.offer.title }}</a>
</td>
<td >{{reservation.user.email}}</td>
<td>{{ reservation.reservation_start_date }}</td>
<td>{{ reservation.reservation_end_date }}</td>
<td> {{ reservation.get_total_cost}} </td>
<td>{{reservation.status}}</td>
</tr>
</tbody>
</table>
{% endblock %}

View File

@ -48,6 +48,37 @@
</tbody>
</table>
{% endif%}
{% if reservations %}
<h4> Rezerwacje klientów </h4>
<table class="table ">
<thead>
<tr>
<th scope="col">Wynajęty kamper</th>
<th scope="col">Uzytkownik </th>
<th scope="col">Początek rezerwacji</th>
<th scope="col">Koniec rezerwacji</th>
<th scope="col"> Koszt </th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
{% for reservation in reservations %}
<tr>
<td>
<a href="{{ reservation.get_absolute_url }}">{{ reservation.offer.title }}</a>
</td>
<td >{{reservation.user.email}}</td>
<td>{{ reservation.reservation_start_date }}</td>
<td>{{ reservation.reservation_end_date }}</td>
<td> {{ reservation.get_total_cost}} </td>
<td> {{reservation.status}} </td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% if user_reservations %}
<h4> Moje rezerwacje </h4>
<table class="table ">
@ -64,7 +95,7 @@
{% for reservation in user_reservations %}
<tr>
<td>
<a href="{{ reservation.offer.get_absolute_url }}">{{ reservation.offer.title }}</a>
<a href="{{ reservation.get_absolute_url }}">{{ reservation.offer.title }}</a>
</td>
<td title="{{ reservation.created_date}}">{{ reservation.created_date }}</td>
<td>{{ reservation.reservation_start_date }}</td>

Some files were not shown because too many files have changed in this diff Show More