asdf

parent dbbb72f7
from django.core.exceptions import ValidationError
from django.forms.models import ModelForm
from django.forms import CharField
from django.forms import CharField, Form
from articles.models import Article, Author, Comment
......@@ -25,21 +25,10 @@ class CommentForm(ModelForm):
class ArticleForm(ModelForm):
body = CharField(max_length=200, required=True, label='Текст', validators=(at_least_10,))
def clean(self):
cleaned_data = super().clean()
print(cleaned_data)
if cleaned_data['body'] == cleaned_data['title']:
raise ValidationError('Текст в названии и теле статьи совпадает')
return cleaned_data
def clean_author(self):
author = self.cleaned_data.get('author')
if author.id == 1:
raise ValidationError(f"У автора {author} слишком много статей!")
return author
class Meta:
model = Article
fields = "__all__"
class SearchForm(Form):
search = CharField(max_length=100, required=False, label="Найти")
from django.shortcuts import render, redirect
from django.views import View
from django.views.generic import TemplateView
class CustomFormView(View):
......@@ -9,6 +10,7 @@ class CustomFormView(View):
def get(self, request, *args, **kwargs):
form = self.form_class()
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
......@@ -30,3 +32,13 @@ class CustomFormView(View):
def get_context_data(self, **kwargs):
return kwargs
class ListView(TemplateView):
model = None
context_key = 'objects'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context[self.context_key] = self.model.objects.all()
return context
\ No newline at end of file
......@@ -2,9 +2,11 @@
{% block content %}
<form action="{% url 'article_create' %}" method="POST">
{% csrf_token %}
<div class="container">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="create">
</div>
</form>
{% endblock %}
\ No newline at end of file
......@@ -2,25 +2,32 @@
{% block content %}
<div class="container">
<form class="d-flex" method="GET">
<input name="search" class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Title</th>
<th scope="col">Author</th>
<th scope="col">Date</th>
</tr>
</thead>
<tbody>
{% for article in articles %}
<tr>
<th scope="row">1</th>
<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.created_at|date:"d M Y" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{% url 'article_create' %}">Создать статью</a>
<a href="{% url 'author_create' %}">Создать автора</a>
{% include 'partial/pagination.html' %}
</div>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block content %}
<div class="container">
<form action="{% url 'article_update' article.pk %}" method="POST">
{% csrf_token %}
<div class="col-md-6">
<label for="title" class="form-label">Название: </label>
<input type="text" name="title" class="form-control" id="title">
</div>
<div class="col-md-6">
<label for="body" class="form-label">Тело статьи: </label>
<textarea name="body" id="body" cols="30" rows="20"></textarea>
</div>
<div class="col-md-6">
<label for="author" class="form-label">Автор: </label>
{{ form.author }}
</div>
<div class="col-md-6">
<label for="tags" class="form-label">Теги: </label>
<select name="tags" id="tags" multiple>
{{ form.tags }}
</select>
</div>
{{ form.as_p }}
<input type="submit" value="create">
</form>
</div>
{% endblock %}
\ No newline at end of file
......@@ -2,6 +2,7 @@
{% block content %}
<div class="container">
<table class="table">
<thead>
<tr>
......@@ -13,7 +14,7 @@
<tbody>
{% for author in authors %}
<tr>
<th scope="row">1</th>
<th scope="row">{{ forloop.counter }}</th>
<td>{{ author.name }}</td>
<td>
<div style="display: flex;">
......@@ -25,6 +26,9 @@
{% endfor %}
</tbody>
</table>
<a href="{% url 'author_create' %}">Создать автора</a>
{% include 'partial/pagination.html' %}
</div>
{% endblock %}
\ No newline at end of file
<style>
.pagination {
text-align: center;
}
.pagination a, .pagination .page-disabled {
display: inline-block;
border: solid 1px #6a7ddd;
border-radius: 3px;
padding: 5px;
margin: 3px;
}
.pagination a {
background: #6a7ddd;
color: white;
text-decoration: none;
}
.pagination a:hover {
background: #6a7dff;
text-decoration: underline;
}
.pagination .page-disabled {
background: #6a7dcc;
color: #dddddd
}
.pagination .current-page {
display: inline-block;
}
.pagination .current-page input {
width: 50px;
padding: 5px 7px;
font-size: inherit;
border-radius: 5px;
text-align: center;
border: solid 1px gray;
}
</style>
<div class="pagination">
<span class="step-links">
<a href="?page=1">&laquo; В начало</a>
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}">Назад</a>
{% else %}
<span class="page-disabled">Назад</span>
{% endif %}
<form class="current-page" method="get">
<label for="page">
Страница <input type="text" name="page" id="page" value="{{ page_obj.number }}">
из {{ page_obj.paginator.num_pages }}.
</label>
</form>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">Далее</a>
{% else %}
<span class="page-disabled">Далее</span>
{% endif %}
<a href="?page={{ page_obj.paginator.num_pages }}">В конец &raquo;</a>
</span>
</div>
\ No newline at end of file
from django.urls import path
from .views import (
article_list_view,
ArticleListView,
ArticleDetailView, CommentView,
author_list_view, author_edit_view, author_delete_view, AuthorView, CreateArticleView, ArticleUpdateView
author_edit_view, author_delete_view, AuthorView, CreateArticleView, ArticleUpdateView, AuthorListView
)
urlpatterns = [
path(
'',
article_list_view,
ArticleListView.as_view(),
name="article_list"
),
path(
......@@ -38,7 +38,7 @@ urlpatterns = [
),
path(
'authors/',
author_list_view,
AuthorListView.as_view(),
name="author_list"
),
......
from django.db.models import Q
from django.shortcuts import render, redirect, get_object_or_404
from django.template.defaultfilters import urlencode
from django.urls import reverse
from django.views import View
from django.views.generic import FormView
from django.views.generic import FormView, ListView
from .helpers.views import CustomFormView
from articles.models import Article, Author
from .forms import AuthorForm, CommentForm, ArticleForm
from .forms import AuthorForm, CommentForm, ArticleForm, SearchForm
def article_list_view(request):
if request.method == "GET":
articles = Article.objects.all()
return render(
request,
template_name="articles/article_list.html",
context={'articles': articles}
)
class ArticleListView(ListView):
form = SearchForm
search_fields = ('title', 'name')
template_name = 'articles/list.html'
model = Article
context_object_name = 'articles'
ordering = ['-created_at']
paginate_by = 5
paginate_orphans = 1
def author_list_view(request):
if request.method == "GET":
authors = Author.objects.all()
return render(
request,
template_name="authors/author_list.html",
context={'authors': authors}
)
def get(self, request, *args, **kwargs):
self.form = self.get_search_form()
self.search_value = self.get_search_value()
return super().get(request, *args, **kwargs)
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=object_list, **kwargs)
context['form'] = self.form
if self.search_value:
context['query'] = urlencode({
'search': self.search_value
})
return context
def get_search_form(self):
return self.form(self.request.GET)
def get_search_value(self):
if self.form.is_valid():
return self.form.cleaned_data.get('search')
def get_queryset(self):
queryset = super().get_queryset()
if self.search_value:
query = Q(title__icontains=self.search_value) | \
Q(author__name__icontains=self.search_value)
queryset = queryset.filter(query)
return queryset
class AuthorListView(ListView):
template_name = 'authors/list.html'
model = Author
context_object_name = 'authors'
ordering = ['name']
paginate_by = 5
class CreateArticleView(CustomFormView):
......@@ -84,8 +115,9 @@ class ArticleUpdateView(FormView):
pk = self.kwargs.get('pk')
return get_object_or_404(Article, pk=pk)
class AuthorView(View):
url_pattern = 'authors/author_create.html'
url_pattern = 'authors/create.html'
def get(self, request, *args, **kwargs):
form = AuthorForm()
......@@ -130,7 +162,7 @@ def create_author_view(request):
form = AuthorForm()
return render(
request,
'authors/author_create.html',
'authors/create.html',
context={'form': form})
if request.method == "POST":
form = AuthorForm(request.POST)
......@@ -145,7 +177,7 @@ def author_edit_view(request, pk):
form = AuthorForm(instance=author)
return render(
request,
'authors/author_update.html',
'authors/update.html',
context={'form': form, "pk": pk})
if request.method == "POST":
form = AuthorForm(request.POST)
......
......@@ -104,7 +104,7 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ru'
TIME_ZONE = 'UTC'
......
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