asdf

parent bcce99eb
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
# 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 .views import login_view, logout_view, register_view
from .views import LoginView, LogoutView, RegisterView, UserDetailView
urlpatterns = [
path('accounts/login', login_view, name='login'),
path('accounts/logout', logout_view, name='logout'),
path('accounts/create/', register_view, name="register")
path('accounts/login', LoginView.as_view(), name='login'),
path('accounts/logout', LogoutView.as_view(), name='logout'),
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 (
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.paginator import Paginator
from django.shortcuts import render, redirect
from django.views import View
from django.views.generic import DetailView
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):
context = {}
print(request.GET)
if request.method == 'POST':
def post(self, request, *args, **kwargs):
context = {}
username = request.POST.get("username")
password = request.POST.get("pass")
user = authenticate(
......@@ -33,25 +46,52 @@ def login_view(request):
return redirect('article_list')
else:
context['has_error'] = True
return render(
request=request,
template_name='login.html',
context=context
)
return render(
request=request,
template_name='login.html',
context=context
)
def register_view(request, *args, **kwargs):
if request.method == "POST":
class RegisterView(View):
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:
form = MyRegisterForm(data=request.POST)
if form.is_valid():
user = form.save()
Profile.objects.create(user=user)
group = Group.objects.get(name="Новые пользователи")
group.user_set.add(user)
login(request, user)
return redirect('article_list')
except ValidationError as e:
print(e)
return render(
request,
template_name='register.html',
context={"form": form})
else:
form = MyRegisterForm()
return render(request, template_name='register.html', context={"form": form})
class UserDetailView(LoginRequiredMixin, DetailView):
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):
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ("text", "author")
fields = ["text", ]
class ArticleForm(Form):
__model = Article
title = CharField()
body = CharField()
author = ModelChoiceField(queryset=Author.objects.all())
tags = ModelMultipleChoiceField(queryset=Tag.objects.all())
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = '__all__'
# class Meta:
# 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 datetime import datetime
......@@ -14,9 +15,9 @@ class Article(models.Model):
created_at = models.DateTimeField(auto_now_add=True, null=False)
author = models.ForeignKey(
"articles.Author",
on_delete=models.SET_NULL,
null=True, related_name='articles')
get_user_model(),
on_delete=models.SET_DEFAULT,
null=True, related_name='articles', default=1)
tags = models.ManyToManyField(
'articles.Tag',
related_name='articles',
......@@ -26,6 +27,11 @@ class Article(models.Model):
def __str__(self):
return f"{self.id}. {self.title[:20]}"
class Meta:
permissions = [
('can_read_article', 'Может читать статьи')
]
class Comment(models.Model):
article = models.ForeignKey(
......@@ -34,7 +40,10 @@ class Comment(models.Model):
on_delete=models.CASCADE,
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="Дата создания")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Дата изменения")
......
......@@ -31,7 +31,9 @@
class="btn btn-success"
value="Оставить комментарий">
</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>
......
......@@ -21,7 +21,7 @@
<tr>
<th scope="row">{{ forloop.counter }}</th>
<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><a class="btn btn-danger btn-sm" href="{% url "article_delete" article.pk %}">Удалить</a></td>
</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 @@
<a class="nav-link" href="{% url 'author_list' %}">Список авторов</a>
</li>
</ul>
{{ 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 'register' %}?next={{ request.get_full_path }}">Регистрация</a>
{% 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>
{% endif %}
</div>
......
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.core.exceptions import PermissionDenied
from django.db.models import Q
from django.shortcuts import get_object_or_404, render, redirect
from django.urls import reverse, reverse_lazy
......@@ -52,7 +55,7 @@ class ArticleListView(ListView):
return queryset
class ArticleCreateView(CreateView):
class ArticleCreateView(LoginRequiredMixin, CreateView):
template_name = 'articles/create.html'
form_class = ArticleForm
model = Article
......@@ -60,12 +63,12 @@ class ArticleCreateView(CreateView):
def get_redirect_url(self):
return reverse('article_detail', kwargs={'pk': self.object.pk})
class ArticleUpdateView(UpdateView):
class ArticleUpdateView(PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
model = Article
template_name = "articles/update.html"
form_class = ArticleForm
context_object_name = 'article'
permission_required = ["articles.change_article", "articles.can_read_article"]
def get_redirect_url(self):
return reverse('article_detail', kwargs={
......
......@@ -15,6 +15,7 @@ class CommentCreateView(CreateView):
def form_valid(self, form):
article = get_object_or_404(Article, pk=self.kwargs.get('pk'))
form.instance.article = article
form.instance.author = self.request.user
return super().form_valid(form)
def get_redirect_url(self):
......
def func(request):
return {
"my_custom_request": 1
}
\ No newline at end of file
......@@ -65,6 +65,7 @@ TEMPLATES = [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'core.context_processor.func'
],
},
},
......@@ -102,6 +103,9 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_URL = "/uploads/"
LOGIN_URL='login'
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
......
......@@ -13,8 +13,11 @@ Including another URLconf
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.urls.static import static
from django.contrib import admin
from django.urls import path, include
from core import settings
from core.error import error_404
handler404 = error_404
......@@ -23,4 +26,4 @@ urlpatterns = [
path('admin/', admin.site.urls),
path('', include('articles.urls')),
path('', include('accounts.urls')),
]
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
body {
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