diff --git a/.gitignore b/.gitignore index fed1b94..2e27876 100644 --- a/.gitignore +++ b/.gitignore @@ -159,4 +159,6 @@ dmypy.json # Cython debug symbols cython_debug/ -users/templates/templates/ \ No newline at end of file +media/ + +demo_data.json diff --git a/README.md b/README.md index fed5aa9..e739e0c 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# First Django web application that is being developed by me \ No newline at end of file +# First Django web application
that is being developed by me \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 deleted file mode 100644 index f84873d..0000000 Binary files a/db.sqlite3 and /dev/null differ diff --git a/password_website/settings.py b/password_website/settings.py index 68116f0..2c50e57 100644 --- a/password_website/settings.py +++ b/password_website/settings.py @@ -77,8 +77,12 @@ DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': os.environ.get('DATABASE_NAME'), + 'USER': os.environ.get('DATABASE_USER'), + 'PASSWORD': os.environ.get('DATABASE_PASSWORD'), + 'HOST': os.environ.get('DATABASE_HOST'), + 'PORT': os.environ.get('DATABASE_PORT'), } } @@ -120,3 +124,6 @@ # https://docs.djangoproject.com/en/2.2/howto/static-files/ STATIC_URL = '/static/' + +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') diff --git a/password_website/urls.py b/password_website/urls.py index 291462e..ca6dffc 100644 --- a/password_website/urls.py +++ b/password_website/urls.py @@ -13,10 +13,11 @@ 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ +from django.conf import settings +from django.conf.urls.static import static from django.contrib import admin from django.urls import path -# from users import views as user_views from users.views import users_views from users.views import usage_views from users.views import countries_views @@ -37,4 +38,4 @@ path('countries//delete', countries_views.countries_delete, name='countries_delete'), path('admin/', admin.site.urls), -] +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0473017 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +Django==2.2.28 +MarkupSafe==2.1.2 +Pillow==9.4.0 +pip==23.0 +pytz==2022.7.1 +setuptools==65.5.1 +sqlparse==0.4.3 +wheel==0.38.4 +psycopg2-binary>=2.8,<2.9 \ No newline at end of file diff --git a/users/admin.py b/users/admin.py index 8c38f3f..1035dc0 100644 --- a/users/admin.py +++ b/users/admin.py @@ -1,3 +1,6 @@ from django.contrib import admin +from .models.users import User +from .models.countries import Country -# Register your models here. +admin.site.register(User) +admin.site.register(Country) diff --git a/users/migrations/0001_initial.py b/users/migrations/0001_initial.py new file mode 100644 index 0000000..b51694c --- /dev/null +++ b/users/migrations/0001_initial.py @@ -0,0 +1,27 @@ +# Generated by Django 2.2.28 on 2023-02-03 19:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=256, verbose_name='First name')), + ('last_name', models.CharField(max_length=256, verbose_name='Last name')), + ('patronymic', models.CharField(blank=True, default='', max_length=256, verbose_name='Patronymic')), + ('birthday', models.DateField(null=True, verbose_name='Date of birth')), + ('photo', models.ImageField(blank=True, null=True, upload_to='', verbose_name='Photo')), + ('telegram_id', models.CharField(max_length=20, verbose_name='Telegram ID')), + ('notes', models.TextField(blank=True, verbose_name='Additional notes')), + ], + ), + ] diff --git a/users/migrations/0002_auto_20230207_1632.py b/users/migrations/0002_auto_20230207_1632.py new file mode 100644 index 0000000..98365f9 --- /dev/null +++ b/users/migrations/0002_auto_20230207_1632.py @@ -0,0 +1,32 @@ +# Generated by Django 2.2.28 on 2023-02-07 16:32 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='user', + options={'verbose_name': 'User', 'verbose_name_plural': 'Users'}, + ), + migrations.CreateModel( + name='Country', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('country_name', models.CharField(max_length=256, verbose_name='Country name')), + ('users_country_number', models.IntegerField(default=1, verbose_name='Country users')), + ('notes', models.TextField(blank=True, verbose_name='Additional notes')), + ('most_active', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.User', verbose_name='Capital')), + ], + options={ + 'verbose_name': 'Country', + 'verbose_name_plural': 'Countries', + }, + ), + ] diff --git a/users/migrations/0003_user_user_country.py b/users/migrations/0003_user_user_country.py new file mode 100644 index 0000000..330d1dd --- /dev/null +++ b/users/migrations/0003_user_user_country.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.28 on 2023-02-07 16:58 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0002_auto_20230207_1632'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='user_country', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='users.Country', verbose_name='Country'), + ), + ] diff --git a/users/migrations/0004_remove_country_users_country_number.py b/users/migrations/0004_remove_country_users_country_number.py new file mode 100644 index 0000000..5f19c2b --- /dev/null +++ b/users/migrations/0004_remove_country_users_country_number.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.28 on 2023-02-07 17:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0003_user_user_country'), + ] + + operations = [ + migrations.RemoveField( + model_name='country', + name='users_country_number', + ), + ] diff --git a/users/migrations/0005_auto_20230207_1703.py b/users/migrations/0005_auto_20230207_1703.py new file mode 100644 index 0000000..599811b --- /dev/null +++ b/users/migrations/0005_auto_20230207_1703.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.28 on 2023-02-07 17:03 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0004_remove_country_users_country_number'), + ] + + operations = [ + migrations.AlterField( + model_name='country', + name='most_active', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.User', verbose_name='Most active user'), + ), + ] diff --git a/users/models.py b/users/models.py deleted file mode 100644 index 71a8362..0000000 --- a/users/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/users/models/__init__.py b/users/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/users/models/countries.py b/users/models/countries.py new file mode 100644 index 0000000..253d7c4 --- /dev/null +++ b/users/models/countries.py @@ -0,0 +1,41 @@ +from django.db import models + +class Country(models.Model): + country_name = models.CharField( + max_length=256, + verbose_name='Country name', + ) + + most_active = models.OneToOneField( + 'User', + blank=True, + null=True, + on_delete=models.SET_NULL, + verbose_name='Most active user', + ) + + # users_country_number = models.IntegerField( + # blank=False, + # default = 1, + # verbose_name = 'Country users' + # ) + + + notes = models.TextField( + blank=True, + verbose_name='Additional notes' + ) + + class Meta: + verbose_name = 'Country' + verbose_name_plural = 'Countries' + + def __str__(self): + if self.most_active: + return '%s (%s %s)' % ( + self.country_name, + self.most_active.first_name, + self.most_active.last_name, + ) + else: + return '%s' % (self.country_name) diff --git a/users/models/users.py b/users/models/users.py new file mode 100644 index 0000000..41a2a2d --- /dev/null +++ b/users/models/users.py @@ -0,0 +1,61 @@ +from django.db import models + +class User(models.Model): + first_name = models.CharField( + max_length=256, + blank=False, + verbose_name='First name' + ) + + last_name = models.CharField( + max_length=256, + blank=False, + verbose_name='Last name' + ) + + patronymic = models.CharField( + max_length=256, + blank=True, + verbose_name='Patronymic', + default='' + ) + + birthday = models.DateField( + blank=False, + verbose_name='Date of birth', + null=True + ) + + photo = models.ImageField( + blank=True, + verbose_name='Photo', + null=True + ) + + telegram_id = models.CharField( + max_length=20, + blank=False, + verbose_name='Telegram ID' + ) + + user_country = models.ForeignKey( + 'Country', + verbose_name='Country', + blank=False, + null=True, + on_delete=models.PROTECT + ) + + notes = models.TextField( + blank=True, + verbose_name='Additional notes' + ) + + class Meta: + verbose_name = 'User' + verbose_name_plural = 'Users' + + def __str__(self): + full_name = '%s %s' % (self.first_name, self.last_name) + + return full_name.strip() diff --git a/users/templates/users/pagination.html b/users/templates/users/pagination.html index 48dc9cb..9178728 100644 --- a/users/templates/users/pagination.html +++ b/users/templates/users/pagination.html @@ -1,31 +1,27 @@ {% load static %} - \ No newline at end of file +{% if users.has_other_pages %} + {% with users_order=request.GET.order_by|default:'last_name' reverse=request.GET.reverse %} + + {% endwith %} +{% endif %} \ No newline at end of file diff --git a/users/templates/users/users_list.html b/users/templates/users/users_list.html index 26abba9..2033f5c 100644 --- a/users/templates/users/users_list.html +++ b/users/templates/users/users_list.html @@ -10,22 +10,54 @@ {% block content %} - - - - - - - - - - + {% with users_order=request.GET.order_by|default:'last_name' reverse=request.GET.reverse %} + + + + + + + + + + + {% endwith %} {% for user in users %} - + + {% if user.photo %} + + {% else %} + + {% endif %} + @@ -52,5 +84,3 @@ {% block pagination %} {% include "users/pagination.html" %} {% endblock pagination %} - -{#{% block footer %} {% endblock footer %}#} \ No newline at end of file diff --git a/users/views/countries_views.py b/users/views/countries_views.py index 62a3274..55c1d6e 100644 --- a/users/views/countries_views.py +++ b/users/views/countries_views.py @@ -1,5 +1,6 @@ from django.http import HttpResponse from django.shortcuts import render +from users.models.countries import Country def countries_list(request): diff --git a/users/views/users_views.py b/users/views/users_views.py index a2d6ea2..4db31a5 100644 --- a/users/views/users_views.py +++ b/users/views/users_views.py @@ -1,33 +1,29 @@ +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.shortcuts import render from django.http import HttpResponse +from users.models.users import User def users_list(request): - users = ( - { - 'id': 1, - 'first_name': 'Taras', - 'last_name': 'Hevlich', - 'telegram_id': 441547155, - 'image': '/img/taras_hevlich.png' - }, - - { - 'id': 2, - 'first_name': 'Polak', - 'last_name': 'Clever', - 'telegram_id': 321453123, - 'image': '/img/default.png' - }, - - { - 'id': 3, - 'first_name': 'Mateusz', - 'last_name': 'Kieliszkowski', - 'telegram_id': 435123555, - 'image': '/img/mateusz_kieliszkowski.png' - }, - ) + users = User.objects.all() + + users_order = request.GET.get('order_by', 'last_name') + + if users_order in ('last_name', 'first_name', 'telegram_id'): + users = users.order_by(users_order) + if request.GET.get('reverse', '') == '1': + users = users.reverse() + + paginator = Paginator(users, 4) + current_page = request.GET.get('page') + + try: + users = paginator.page(current_page) + except PageNotAnInteger: + users = paginator.page(1) + except EmptyPage: + users = paginator.page(paginator.num_pages) + return render(request, 'users/users_list.html', {'users': users})
PhotoLast Name ↑First NameTelegram IDActions
Photo + + Last Name + {% if users_order == 'last_name' and reverse != '1' %}↑ + {% elif users_order == 'last_name' and reverse == '1' %}↓ + {% endif %} + + + + First Name + {% if users_order == 'first_name' and reverse != '1' %}↑ + {% elif users_order == 'first_name' and reverse == '1' %}↓ + {% endif %} + + + + Telegram ID + {% if users_order == 'telegram_id' and reverse != '1' %}↑ + {% elif users_order == 'telegram_id' and reverse == '1' %}↓ + {% endif %} + + Actions
{{ forloop.counter }}{{ user.last_name }} {{ user.first_name }} {{ user.telegram_id }}