asdf

parent bcce99eb
from django.contrib import admin from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
# Register your models here. from accounts.models import Profile
class ProfileInline(admin.StackedInline):
model = Profile
fields = ['birth_date', 'avatar']
class ProfileAdmin(UserAdmin):
inlines = [ProfileInline]
User = get_user_model()
admin.site.unregister(User)
admin.site.register(User, ProfileAdmin)
\ No newline at end of file
# Generated by Django 3.2.6 on 2021-09-16 11:29
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('birth_date', models.DateField(blank=True, null=True, verbose_name='Дата рождения')),
('avatar', models.ImageField(blank=True, null=True, upload_to='user_pics', verbose_name='Аватар')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL, verbose_name='Пользователь')),
],
options={
'verbose_name': 'Профиль',
'verbose_name_plural': 'Профили',
},
),
]
# Generated by Django 3.2.6 on 2021-09-16 14:47
from django.db import migrations
def create_profiles(apps, schema_editor):
User = apps.get_model('auth', 'User')
Profile = apps.get_model('accounts', 'Profile')
for user in User.objects.all():
Profile.objects.get_or_create(user=user)
class Migration(migrations.Migration):
dependencies = [
('accounts', '0001_initial'),
]
operations = [
migrations.RunPython(create_profiles, migrations.RunPython.noop)
]
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractUser
from django.db import models from django.db import models
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(
get_user_model(),
related_name='profile',
on_delete=models.CASCADE,
verbose_name="Пользователь"
)
birth_date = models.DateField(
null=True,
blank=True,
verbose_name="Дата рождения"
)
avatar = models.ImageField(null=True, blank=True,
upload_to='user_pics', verbose_name="Аватар")
def __str__(self):
return self.user.get_full_name() + "профиль"
class Meta:
verbose_name = "профиль"
verbose_name_plural = "профили"
{% extends 'base.html' %}
{% block title %}Пользователь{% endblock %}
{% block menu_links %}
<li><a href="#">Редактировать</a></li>
<li><a href="#">Смена пароля</a></li>
{% endblock %}
{% block content %}
<div class="container">
<h1>Личная страница пользователя {{ user_obj.get_full_name|default:user_obj.username }}</h1>
{% if user_obj.profile.avatar %}
<img class="avatar" src="{{ user_obj.profile.avatar.url }}" width="250" height="250" alt="user picture">
{% 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 clear">Статьи автора:</h2>
{% include 'partial/article_list.html' %}
</div>
{% endblock %}
from django.urls import path from django.urls import path
from .views import login_view, logout_view, register_view from .views import LoginView, LogoutView, RegisterView, UserDetailView
urlpatterns = [ urlpatterns = [
path('accounts/login', login_view, name='login'), path('accounts/login', LoginView.as_view(), name='login'),
path('accounts/logout', logout_view, name='logout'), path('accounts/logout', LogoutView.as_view(), name='logout'),
path('accounts/create/', register_view, name="register") path('accounts/create/', RegisterView.as_view(), name="register"),
path('<int:pk>/', UserDetailView.as_view(), name='user-detail')
] ]
\ No newline at end of file
from django.contrib.auth import ( from django.contrib.auth import (
authenticate, login, logout authenticate, login, logout, get_user_model
) )
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import Group
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.paginator import Paginator
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.views import View
from django.views.generic import DetailView
from .forms import RegisterForm, MyRegisterForm from .forms import RegisterForm, MyRegisterForm
from .models import Profile
class LogoutView(View):
def get(self, request, *args, **kwargs):
logout(request)
next = request.GET.get('next')
if next:
return redirect(next)
return redirect('login')
def logout_view(request):
logout(request)
next = request.GET.get('next')
if next:
return redirect(next)
return redirect('login')
class LoginView(View):
def get(self, request, *args, **kwargs):
return render(
request=request,
template_name='login.html',
)
def login_view(request): def post(self, request, *args, **kwargs):
context = {} context = {}
print(request.GET)
if request.method == 'POST':
username = request.POST.get("username") username = request.POST.get("username")
password = request.POST.get("pass") password = request.POST.get("pass")
user = authenticate( user = authenticate(
...@@ -33,25 +46,52 @@ def login_view(request): ...@@ -33,25 +46,52 @@ def login_view(request):
return redirect('article_list') return redirect('article_list')
else: else:
context['has_error'] = True context['has_error'] = True
return render( return render(
request=request, request=request,
template_name='login.html', template_name='login.html',
context=context context=context
) )
def register_view(request, *args, **kwargs): class RegisterView(View):
if request.method == "POST": def get(self, request, *args, **kwargs):
form = MyRegisterForm()
return render(
request,
template_name='register.html',
context={"form": form})
def post(self, request, *args, **kwargs):
try: try:
form = MyRegisterForm(data=request.POST) form = MyRegisterForm(data=request.POST)
if form.is_valid(): if form.is_valid():
user = form.save() user = form.save()
Profile.objects.create(user=user)
group = Group.objects.get(name="Новые пользователи")
group.user_set.add(user)
login(request, user) login(request, user)
return redirect('article_list') return redirect('article_list')
except ValidationError as e: except ValidationError as e:
print(e) print(e)
return render(
request,
template_name='register.html',
context={"form": form})
else:
form = MyRegisterForm() class UserDetailView(LoginRequiredMixin, DetailView):
return render(request, template_name='register.html', context={"form": form}) model = get_user_model()
template_name = "user_detail.html"
context_object_name = "user_obj"
paginate_related_by = 5
paginate_related_orphans = 0
def get_context_data(self, **kwargs):
articles = self.object.articles.order_by('-created_at')
paginator = Paginator(articles, self.paginate_related_by, self.paginate_related_orphans)
page_number = self.request.GET.get('page', 1)
page = paginator.get_page(page_number)
kwargs['page_obj'] = page
kwargs['articles'] = page.object_list
kwargs['is_paginated'] = page.has_other_pages()
return super(UserDetailView, self).get_context_data(**kwargs)
...@@ -22,15 +22,13 @@ class AuthorForm(ModelForm): ...@@ -22,15 +22,13 @@ class AuthorForm(ModelForm):
class CommentForm(ModelForm): class CommentForm(ModelForm):
class Meta: class Meta:
model = Comment model = Comment
fields = ("text", "author") fields = ["text", ]
class ArticleForm(Form): class ArticleForm(ModelForm):
__model = Article class Meta:
title = CharField() model = Article
body = CharField() fields = '__all__'
author = ModelChoiceField(queryset=Author.objects.all())
tags = ModelMultipleChoiceField(queryset=Tag.objects.all())
# class Meta: # class Meta:
# model = Article # model = Article
......
# Generated by Django 3.2.6 on 2021-09-13 14:45
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('articles', '0015_alter_article_created_at'),
]
operations = [
migrations.AlterField(
model_name='article',
name='author',
field=models.ForeignKey(default=1, null=True, on_delete=django.db.models.deletion.SET_DEFAULT, related_name='articles', to=settings.AUTH_USER_MODEL),
),
]
# Generated by Django 3.2.6 on 2021-09-13 14:49
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('articles', '0016_alter_article_author'),
]
operations = [
migrations.AlterField(
model_name='comment',
name='author',
field=models.ForeignKey(default=1, null=True, on_delete=django.db.models.deletion.SET_DEFAULT, related_name='author_of_comment', to=settings.AUTH_USER_MODEL),
),
]
# Generated by Django 3.2.6 on 2021-09-13 14:56
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('articles', '0017_alter_comment_author'),
]
operations = [
migrations.AlterModelOptions(
name='article',
options={'permissions': [('can_read_article', 'Может читать статьи')]},
),
]
from django.contrib.auth import get_user_model
from django.db import models from django.db import models
from datetime import datetime from datetime import datetime
...@@ -14,9 +15,9 @@ class Article(models.Model): ...@@ -14,9 +15,9 @@ class Article(models.Model):
created_at = models.DateTimeField(auto_now_add=True, null=False) created_at = models.DateTimeField(auto_now_add=True, null=False)
author = models.ForeignKey( author = models.ForeignKey(
"articles.Author", get_user_model(),
on_delete=models.SET_NULL, on_delete=models.SET_DEFAULT,
null=True, related_name='articles') null=True, related_name='articles', default=1)
tags = models.ManyToManyField( tags = models.ManyToManyField(
'articles.Tag', 'articles.Tag',
related_name='articles', related_name='articles',
...@@ -26,6 +27,11 @@ class Article(models.Model): ...@@ -26,6 +27,11 @@ class Article(models.Model):
def __str__(self): def __str__(self):
return f"{self.id}. {self.title[:20]}" return f"{self.id}. {self.title[:20]}"
class Meta:
permissions = [
('can_read_article', 'Может читать статьи')
]
class Comment(models.Model): class Comment(models.Model):
article = models.ForeignKey( article = models.ForeignKey(
...@@ -34,7 +40,10 @@ class Comment(models.Model): ...@@ -34,7 +40,10 @@ class Comment(models.Model):
on_delete=models.CASCADE, on_delete=models.CASCADE,
verbose_name="Статья") verbose_name="Статья")
text = models.TextField(max_length=400, verbose_name="Комментарий") text = models.TextField(max_length=400, verbose_name="Комментарий")
author = models.CharField(max_length=40, null=True, blank=True, verbose_name="Автор", default="Аноним") author = models.ForeignKey(
get_user_model(),
on_delete=models.SET_DEFAULT,
null=True, related_name='author_of_comment', default=1)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания") created_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Дата изменения") updated_at = models.DateTimeField(auto_now=True, verbose_name="Дата изменения")
......
...@@ -31,7 +31,9 @@ ...@@ -31,7 +31,9 @@
class="btn btn-success" class="btn btn-success"
value="Оставить комментарий"> value="Оставить комментарий">
</form> </form>
<a href="{% url 'article_update' article.pk %}">Изменить статью</a> {% if perms.articles.change_article %}
<a href="{% url 'article_update' article.pk %}">Изменить статью</a>
{% endif %}
</div> </div>
</div> </div>
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<tr> <tr>
<th scope="row">{{ forloop.counter }}</th> <th scope="row">{{ forloop.counter }}</th>
<td><a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a></td> <td><a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a></td>
<td>{{ article.author.name }}</td> <td>{{ article.author }}</td>
<td>{{ article.created_at|date:"d M Y" }}</td> <td>{{ article.created_at|date:"d M Y" }}</td>
<td><a class="btn btn-danger btn-sm" href="{% url "article_delete" article.pk %}">Удалить</a></td> <td><a class="btn btn-danger btn-sm" href="{% url "article_delete" article.pk %}">Удалить</a></td>
</tr> </tr>
......
{% if is_paginated %}
{% include 'partial/pagination.html' %}
{% endif %}
{% for article in articles %}
<div class="box">
<h3><a href="{% url "article_detail" article.pk %}">{{ article.title }}</a></h3>
<p>
<label for="selected_articles-{{ article.pk }}">Select:</label>
<input type="checkbox" name="selected_articles"
id="selected_articles-{{ article.pk }}" value="{{ article.pk }}">
</p>
<p>Статус: ({{ article.status }} | {{ article.get_status_display }})</p>
<p>
<a href="{% url 'user-detail' article.author_id %}">{{ article.author }}</a>
| {{ article.created_at|date:"d.m.Y H:i:s" }}
</p>
<p>Published at: {{ article.publish_at|date:"d.m.Y H:i:s" }}</p>
{% if perms.articles.change_article or article.author == request.user %}
<p><a href="{% url 'article_update' article.pk %}">Update</a></p>
{% endif %}
{% if perms.articles.delete_article or article.author == request.user %}
<p><a href="{% url 'article_delete' article.pk %}">Delete</a></p>
{% endif %}
</div>
{% empty %}
<h2 class="text-center">Нет статей</h2>
{% endfor %}
{% if is_paginated %}
{% include 'partial/pagination.html' %}
{% endif %}
...@@ -10,11 +10,11 @@ ...@@ -10,11 +10,11 @@
<a class="nav-link" href="{% url 'author_list' %}">Список авторов</a> <a class="nav-link" href="{% url 'author_list' %}">Список авторов</a>
</li> </li>
</ul> </ul>
{{ user.is_authenticated }}
{% if not user.is_authenticated %} {% if not user.is_authenticated %}
<a class="btn btn-success" href="{% url 'login' %}?next={{ request.get_full_path }}">Войти</a> <a class="btn btn-success" href="{% url 'login' %}?next={{ request.get_full_path }}">Войти</a>
<a class="btn btn-success" href="{% url 'register' %}?next={{ request.get_full_path }}">Регистрация</a> <a class="btn btn-success" href="{% url 'register' %}?next={{ request.get_full_path }}">Регистрация</a>
{% else %} {% else %}
<li class="menu-right">Привет, <a href="{% url 'user-detail' user.pk %}">{{ user.username }}</a>!</li>
<a class="btn btn-danger" href="{% url 'logout' %}?next={{ request.get_full_path }}">Выйти</a> <a class="btn btn-danger" href="{% url 'logout' %}?next={{ request.get_full_path }}">Выйти</a>
{% endif %} {% endif %}
</div> </div>
......
from urllib.parse import urlencode from urllib.parse import urlencode
from django.contrib.auth.mixins import LoginRequiredMixin
import P as P
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.db.models import Q from django.db.models import Q
from django.shortcuts import get_object_or_404, render, redirect from django.shortcuts import get_object_or_404, render, redirect
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
...@@ -52,7 +55,7 @@ class ArticleListView(ListView): ...@@ -52,7 +55,7 @@ class ArticleListView(ListView):
return queryset return queryset
class ArticleCreateView(CreateView): class ArticleCreateView(LoginRequiredMixin, CreateView):
template_name = 'articles/create.html' template_name = 'articles/create.html'
form_class = ArticleForm form_class = ArticleForm
model = Article model = Article
...@@ -60,12 +63,12 @@ class ArticleCreateView(CreateView): ...@@ -60,12 +63,12 @@ class ArticleCreateView(CreateView):
def get_redirect_url(self): def get_redirect_url(self):
return reverse('article_detail', kwargs={'pk': self.object.pk}) return reverse('article_detail', kwargs={'pk': self.object.pk})
class ArticleUpdateView(PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
class ArticleUpdateView(UpdateView):
model = Article model = Article
template_name = "articles/update.html" template_name = "articles/update.html"
form_class = ArticleForm form_class = ArticleForm
context_object_name = 'article' context_object_name = 'article'
permission_required = ["articles.change_article", "articles.can_read_article"]
def get_redirect_url(self): def get_redirect_url(self):
return reverse('article_detail', kwargs={ return reverse('article_detail', kwargs={
......
...@@ -15,6 +15,7 @@ class CommentCreateView(CreateView): ...@@ -15,6 +15,7 @@ class CommentCreateView(CreateView):
def form_valid(self, form): def form_valid(self, form):
article = get_object_or_404(Article, pk=self.kwargs.get('pk')) article = get_object_or_404(Article, pk=self.kwargs.get('pk'))
form.instance.article = article form.instance.article = article
form.instance.author = self.request.user
return super().form_valid(form) return super().form_valid(form)
def get_redirect_url(self): def get_redirect_url(self):
......
def func(request):
return {
"my_custom_request": 1
}
\ No newline at end of file
...@@ -65,6 +65,7 @@ TEMPLATES = [ ...@@ -65,6 +65,7 @@ TEMPLATES = [
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
'core.context_processor.func'
], ],
}, },
}, },
...@@ -102,6 +103,9 @@ AUTH_PASSWORD_VALIDATORS = [ ...@@ -102,6 +103,9 @@ AUTH_PASSWORD_VALIDATORS = [
}, },
] ]
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_URL = "/uploads/"
LOGIN_URL='login' LOGIN_URL='login'
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/ # https://docs.djangoproject.com/en/3.2/topics/i18n/
......
...@@ -13,8 +13,11 @@ Including another URLconf ...@@ -13,8 +13,11 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path 1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from core import settings
from core.error import error_404 from core.error import error_404
handler404 = error_404 handler404 = error_404
...@@ -23,4 +26,4 @@ urlpatterns = [ ...@@ -23,4 +26,4 @@ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('', include('articles.urls')), path('', include('articles.urls')),
path('', include('accounts.urls')), path('', include('accounts.urls')),
] ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
body { body {
background: aqua; background: aqua;
} }
\ No newline at end of file
.avatar {
display: inline-block;
float: left;
width: 250px;
height: auto;
margin-right: 20px;
margin-bottom: 20px;
}
.text-center {
text-align: center;
}
.clear {
clear: both;
}
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