Add more data to model and login

This commit is contained in:
Nyymix 2025-08-09 22:53:35 +03:00
parent 783e5e92cb
commit 522322b1e1
8 changed files with 147 additions and 6 deletions

View file

@ -6,7 +6,8 @@ from .models import FuelPurchase
class FuelPurchaseForm(forms.ModelForm):
class Meta:
model = FuelPurchase
fields = ['purchase_date', 'total_cost', 'price_per_litre', 'amount_litres']
fields = ['purchase_date', 'total_cost', 'price_per_litre', 'amount_litres', 'octane', 'gas_station', 'car',]
widgets = {
'purchase_date': forms.DateInput(attrs={
'type': 'date',
@ -28,4 +29,8 @@ class FuelPurchaseForm(forms.ModelForm):
'id': 'id_amount_litres',
'readonly': True
}),
'octane': forms.Select(attrs={'class': 'uk-select'}),
'gas_station': forms.Select(attrs={'class': 'uk-select'}),
'car': forms.Select(attrs={'class': 'uk-select'}),
}

View file

@ -0,0 +1,31 @@
# Generated by Django 5.2.5 on 2025-08-09 18:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0001_initial'),
]
operations = [
migrations.RemoveConstraint(
model_name='fuelpurchase',
name='unique_fuel_purchase',
),
migrations.AddField(
model_name='fuelpurchase',
name='gas_station',
field=models.IntegerField(choices=[(0, '-'), (1, 'Neste'), (2, 'Teboil'), (3, 'ABC'), (4, 'Shell'), (5, 'St1'), (6, 'SEO'), (7, 'ysi5')], default=1, verbose_name='Gas Station'),
),
migrations.AddField(
model_name='fuelpurchase',
name='octane',
field=models.IntegerField(choices=[(95, '95'), (98, '98')], default=95, verbose_name='Octane'),
),
migrations.AddConstraint(
model_name='fuelpurchase',
constraint=models.UniqueConstraint(fields=('purchase_date', 'total_cost', 'price_per_litre', 'amount_litres', 'octane', 'gas_station'), name='unique_fuel_purchase'),
),
]

View file

@ -0,0 +1,26 @@
# Generated by Django 5.2.5 on 2025-08-09 19:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0002_remove_fuelpurchase_unique_fuel_purchase_and_more'),
]
operations = [
migrations.RemoveConstraint(
model_name='fuelpurchase',
name='unique_fuel_purchase',
),
migrations.AddField(
model_name='fuelpurchase',
name='car',
field=models.IntegerField(choices=[(0, '_'), (1, 'Renault'), (2, 'Nissan'), (3, 'Smart')], default=3, verbose_name='Car'),
),
migrations.AddConstraint(
model_name='fuelpurchase',
constraint=models.UniqueConstraint(fields=('purchase_date', 'total_cost', 'price_per_litre', 'amount_litres', 'octane', 'gas_station', 'car'), name='unique_fuel_purchase'),
),
]

View file

@ -3,10 +3,37 @@ from django.db.models import F, Q
class FuelPurchase(models.Model):
GAS_STATION_CHOICES = [
(0, '-'),
(1, 'Neste'),
(2, 'Teboil'),
(3, 'ABC'),
(4, 'Shell'),
(5, 'St1'),
(6, 'SEO'),
(7, 'ysi5'),
]
OCTANE_CHOICES = [
(95, '95'),
(98, '98'),
]
CAR_CHOICES = [
(0, '_'),
(1, 'Renault'),
(2, 'Nissan'),
(3, 'Smart'),
]
purchase_date = models.DateField(null=False, blank=False, verbose_name="Purchase Date")
total_cost = models.DecimalField(null=False, blank=False, max_digits=10, decimal_places=2, verbose_name="Total Cost (€)")
price_per_litre = models.DecimalField(null=False, blank=False, max_digits=6, decimal_places=3, verbose_name="Price per Litre (€)")
amount_litres = models.DecimalField(null=False, blank=False, max_digits=7, decimal_places=2, verbose_name="Amount (litres)")
octane = models.IntegerField(choices=OCTANE_CHOICES, default=95, verbose_name="Octane")
gas_station = models.IntegerField(choices=GAS_STATION_CHOICES, default=1, verbose_name="Gas Station")
car = models.IntegerField(choices=CAR_CHOICES, default=3, verbose_name="Car")
class Meta:
constraints = [
@ -16,6 +43,9 @@ class FuelPurchase(models.Model):
'total_cost',
'price_per_litre',
'amount_litres',
'octane',
'gas_station',
'car',
],
name='unique_fuel_purchase'
),

View file

@ -14,12 +14,12 @@
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-small-bottom">
<a href="{% url 'fuelpurchase_list' prev_year prev_month %}" class="uk-button uk-button-default">&larr; Previous</a>
<form method="get" action="" onChange="if(this.value) window.location.href=this.value;" class="uk-form-horizontal">
<select class="uk-select">
<form method="get" action="" class="uk-form-horizontal">
<select class="uk-select" onchange="if(this.value) window.location.href=this.value;">
{% for month_date in available_months %}
<option value="{% url 'fuelpurchase_list' month_date.year month_date.month %}"
{% if month_date.year == current_year and month_date.month == current_month %}selected{% endif %}>
{{ month_date|date:"F Y" }}
{{ month_date|date:"Y F" }}
</option>
{% endfor %}
</select>
@ -32,7 +32,7 @@
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
<h4 class="uk-card-title">Summary</h4>
<ul class="uk-list uk-list-divider">
<li><strong>Total Cost:</strong> {{ summary.total_cost_sum|default:"0.00" }} €</li>
<li><strong>Total Cost:</strong> {{ summary.total_cost_sum|floatformat:2|default:"0.00" }} €</li>
<li><strong>Total Litres:</strong> {{ summary.total_litres_sum|floatformat:2|default:"0.00" }} L</li>
<li><strong>Average Litre Price:</strong> {{ summary.avg_price|floatformat:3|default:"0.000" }} €</li>
<li><strong>Min Litre Price:</strong> {{ summary.min_price|floatformat:3|default:"0.000" }} €</li>
@ -49,6 +49,9 @@
<th>Total Cost (€)</th>
<th>Litre Price (€)</th>
<th>Amount (litres)</th>
<th>Octane</th>
<th>Gas Station</th>
<th>Car</th>
</tr>
</thead>
<tbody>
@ -58,6 +61,9 @@
<td>{{ purchase.total_cost }}</td>
<td>{{ purchase.price_per_litre }}</td>
<td>{{ purchase.amount_litres }}</td>
<td>{{ purchase.octane }}</td>
<td>{{ purchase.get_gas_station_display }}</td>
<td>{{ purchase.get_car_display }}</td>
</tr>
{% endfor %}
</tbody>

View file

@ -0,0 +1,38 @@
{% extends "base.html" %}
{% block content %}
<div class="uk-flex uk-flex-center uk-margin-large-top">
<form method="post" class="uk-form-stacked uk-card uk-card-default uk-card-body uk-width-1-3@m">
{% csrf_token %}
<fieldset class="uk-fieldset">
<legend class="uk-legend uk-text-center">Kirjaudu sisään</legend>
{% if form.errors %}
<div class="uk-alert-danger" uk-alert>
<p>Virheellinen käyttäjätunnus tai salasana.</p>
</div>
{% endif %}
<div class="uk-margin">
<label class="uk-form-label" for="id_username">Käyttäjätunnus</label>
<div class="uk-form-controls">
<input class="uk-input" type="text" name="username" autofocus required id="id_username" value="{{ form.username.value|default_if_none:'' }}">
</div>
</div>
<div class="uk-margin">
<label class="uk-form-label" for="id_password">Salasana</label>
<div class="uk-form-controls">
<input class="uk-input" type="password" name="password" required id="id_password">
</div>
</div>
<div class="uk-margin uk-text-center">
<button type="submit" class="uk-button uk-button-primary uk-width-1-1">Kirjaudu</button>
</div>
</fieldset>
</form>
</div>
{% endblock %}

View file

@ -1,3 +1,4 @@
from django.contrib.auth import views as auth_views
from django.urls import path
from . import views
@ -6,4 +7,6 @@ urlpatterns = [
path("", views.FuelPurchaseMonthlyListView.as_view(), name="fuelpurchase_list_current"),
path("<int:year>/<int:month>/", views.FuelPurchaseMonthlyListView.as_view(), name="fuelpurchase_list"),
path("add/", views.FuelPurchaseCreateView.as_view(), name="fuelpurchase_add"),
path('accounts/login/', auth_views.LoginView.as_view(template_name='registration/login.html'), name='login'),
path('accounts/logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'),
]

View file

@ -1,6 +1,8 @@
from calendar import monthrange
from datetime import date, timedelta
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Avg, Max, Min, Sum
from django.http import HttpResponse
from django.shortcuts import render
@ -63,7 +65,7 @@ class FuelPurchaseMonthlyListView(ListView):
return context
class FuelPurchaseCreateView(CreateView):
class FuelPurchaseCreateView(LoginRequiredMixin, CreateView):
model = FuelPurchase
form_class = FuelPurchaseForm
template_name = "main/fuelpurchase_add.html"