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 %}
-
-
- | № |
- Photo |
- Last Name ↑ |
- First Name |
- Telegram ID |
- Actions |
-
-
+ {% with users_order=request.GET.order_by|default:'last_name' reverse=request.GET.reverse %}
+
+
+ | № |
+ 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 |
+
+
+ {% endwith %}
{% for user in users %}
| {{ forloop.counter }} |
-  |
+
+ {% if user.photo %}
+  |
+ {% else %}
+  |
+ {% endif %}
+
{{ user.last_name }} |
{{ user.first_name }} |
{{ user.telegram_id }} |
@@ -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})