Commit 90c2d2d3 authored by Давид Ли's avatar Давид Ли

lesson 60

parent 97811be9
from django.contrib import admin
from accounts.models import User
from django.contrib.auth.admin import UserAdmin
from accounts import models
admin.site.register(User)
# admin.site.register(User)
class ProfileInline(admin.StackedInline):
model = models.Profile
fields = ['birth_date', 'avatar']
class MyUserAdmin(UserAdmin):
inlines = [ProfileInline]
admin.site.register(models.User, MyUserAdmin)
# Generated by Django 3.2.19 on 2024-02-29 13:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('accounts', '0004_alter_user_is_active'),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('birth_date', models.DateField(null=True, verbose_name='Дата рождения')),
('avatar', models.ImageField(null=True, upload_to='avatars', verbose_name='Аватар')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Пользователь')),
],
options={
'verbose_name': 'Профиль',
'verbose_name_plural': 'Профили',
},
),
]
# Generated by Django 3.2.19 on 2024-02-29 14:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0005_profile'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='avatar',
field=models.ImageField(default='avatars/no_image.jpeg', null=True, upload_to='avatars', verbose_name='Аватар'),
),
]
......@@ -18,3 +18,20 @@ class User(AbstractUser):
),
)
password = models.CharField(max_length=128, verbose_name='password', null=True)
# Pillow
# sudo apt-get install libjpeg-dev zlib1g-dev
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name='Пользователь')
birth_date = models.DateField(null=True, verbose_name='Дата рождения')
avatar = models.ImageField(null=True, upload_to='avatars', verbose_name='Аватар', default='avatars/no_image.jpeg')
class Meta:
verbose_name = 'Профиль'
verbose_name_plural = 'Профили'
def __str__(self):
return self.user.get_full_name()
from accounts.views import RegisterView
from accounts import views
from django.urls import path
from django.contrib.auth.views import LoginView, LogoutView
......@@ -7,5 +7,6 @@ from django.contrib.auth.views import LoginView, LogoutView
urlpatterns = [
path('login', LoginView.as_view(template_name='auth/login.html'), name='login'),
path('logout', LogoutView.as_view(), name='logout'),
path('register', RegisterView.as_view(), name='register'),
path('register', views.RegisterView.as_view(), name='register'),
path('<int:id>/', views.UserDetailView.as_view(), name='profile'),
]
from django.http import HttpRequest
from django.urls import reverse
from accounts import forms
from accounts import forms, models
from django.views import generic
from django.contrib.auth import login, get_user_model
from django.contrib.auth import login, get_user_model, mixins
from django.shortcuts import redirect
from django.core import exceptions
from django.core.paginator import Paginator
class RegisterView(generic.CreateView):
......@@ -56,3 +58,33 @@ class RegisterView(generic.CreateView):
'next',
self.request.GET.get('next', 'index')
)
class UserDetailView(mixins.LoginRequiredMixin, generic.DetailView):
model = get_user_model()
template_name = 'auth/user_detail.html'
context_object_name = 'user_obj'
pk_url_kwarg = 'id'
paginate_by = 3
paginate_orphans = 0
def __get_paginator(self):
articles = self.object.articles.order_by('-created_at')
return Paginator(articles, self.paginate_by, self.paginate_orphans)
def get_context_data(self, **kwargs):
# Проверяем, если профиль привязанный к нашему юзеру уже есть, то ничего не делать
# Если нет, то создать пустой профиль
models.Profile.objects.get_or_create(user=self.object)
paginator = self.__get_paginator()
page_number = self.request.GET.get('page', 1)
page = paginator.get_page(page_number)
return super().get_context_data(
**kwargs,
paginator=paginator,
page_obj=page,
is_paginated=page.has_other_pages(),
)
......@@ -137,3 +137,8 @@ LOGIN_REDIRECT_URL = LOGOUT_REDIRECT_URL = 'index'
LOGIN_URL = 'login'
AUTH_USER_MODEL = 'accounts.User'
# MEDIA
MEDIA_ROOT = BASE_DIR / 'uploads'
MEDIA_URL = '/images/'
# localhost:1025/uploads/avatars/user_1.jpg
......@@ -15,6 +15,8 @@ Including another URLconf
"""
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from webapp import views
......@@ -24,4 +26,5 @@ urlpatterns = [
path('articles/', include('webapp.urls')),
path('accounts/', include('accounts.urls')),
]
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
{% extends 'base.html' %}
{% block content %}
<h1>Личная страница пользователя {{ user_obj.get_full_name }}</h1>
{% if user_obj.profile.avatar %}
<img src="{{ user_obj.profile.avatar.url }}" width="250" height="250" class="object-fit-cover" alt="user_avatar">
{% endif %}
<p>Имя пользователя: {{ user_obj.username }}</p>
<p>Имя: {{ user_obj.first_name }}</p>
<p>Фамилия: {{ user_obj.last_name }}</p>
<p>Дата Рождения: {{ user_obj.profile.birth_date|date:'d.m.Y' }}</p>
<p>Почта: {{ user_obj.email }}</p>
<h2 class="text-center">Статьи</h2>
{{page_obj.has_other_pages}}
{% include 'partial/article_list.html' with articles=page_obj.object_list is_paginated=page_obj.has_other_pages %}
{% endblock %}
\ No newline at end of file
......@@ -35,7 +35,9 @@
<a class="nav-link" href="{% url 'logout' %}?next={{ request.get_full_path }}">Logout</a>
</li>
<li class="nav-item">
<span class="nav-link fw-bold">Hello, {{ user.username }}</span>
<span class="nav-link fw-bold">
Hello, <a href="{% url 'profile' user.id %}" class="text-decoration-none text-secondary">{{ user.username }}</a>
</span>
</li>
{% else %}
......
......@@ -6,17 +6,7 @@
<p><a href="{% url 'articles_add' %}">Добавить</a></p>
{% for article in articles %}
<h2>{{ article.title }}</h2>
<a href="{% url 'articles_detail' id=article.id %}">Подробнее...</a>
<hr>
{% empty %}
<h2>no articles yet ...</h2>
{% endfor %}
{% include 'partial/article_list.html' %}
</div>
{% if is_paginated %}
{% include 'partial/pagination.html' %}
{% endif %}
{% endblock %}
\ No newline at end of file
{% for article in articles %}
<h2>{{ article.title }}</h2>
<a href="{% url 'articles_detail' id=article.id %}">Подробнее...</a>
<hr>
{% empty %}
<h2>no articles yet ...</h2>
{% endfor %}
{% if is_paginated %}
{% include 'partial/pagination.html' %}
{% endif %}
<div class="d-flex justify-content-center">
<div class="d-flex justify-content-center mt-5">
<nav aria-label="...">
<ul class="pagination">
{% if page_obj.has_previous %}
......
asgiref==3.7.2
Django==3.2.23
pytz==2023.3.post1
sqlparse==0.4.4
Pillow==10.0.0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment