Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
A
article_proj
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Владислав Андреев
article_proj
Commits
3d18edc3
Commit
3d18edc3
authored
Aug 25, 2021
by
Владислав Андреев
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
asdf
parent
dbbb72f7
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
179 additions
and
45 deletions
+179
-45
forms.py
articles/forms.py
+5
-16
views.py
articles/helpers/views.py
+12
-0
create.html
articles/templates/articles/create.html
+3
-1
list.html
articles/templates/articles/list.html
+8
-1
update.html
articles/templates/articles/update.html
+20
-0
create.html
articles/templates/authors/create.html
+0
-0
list.html
articles/templates/authors/list.html
+5
-1
update.html
articles/templates/authors/update.html
+0
-0
pagination.html
articles/templates/partial/pagination.html
+68
-0
urls.py
articles/urls.py
+4
-4
views.py
articles/views.py
+53
-21
settings.py
core/settings.py
+1
-1
No files found.
articles/forms.py
View file @
3d18edc3
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
=
"Найти"
)
articles/helpers/views.py
View file @
3d18edc3
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
articles/templates/articles/create.html
View file @
3d18edc3
...
...
@@ -2,9 +2,11 @@
{% block content %}
<form
action=
"{% url 'article_create' %}"
method=
"POST"
>
<div
class=
"container"
>
{% csrf_token %}
{{ form.as_p }}
<input
type=
"submit"
value=
"create"
>
</div>
</form>
{% endblock %}
\ No newline at end of file
articles/templates/articles/
article_
list.html
→
articles/templates/articles/list.html
View file @
3d18edc3
...
...
@@ -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
articles/templates/articles/update.html
View file @
3d18edc3
{% 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
articles/templates/authors/
author_
create.html
→
articles/templates/authors/create.html
View file @
3d18edc3
File moved
articles/templates/authors/
author_
list.html
→
articles/templates/authors/list.html
View file @
3d18edc3
...
...
@@ -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
articles/templates/authors/
author_
update.html
→
articles/templates/authors/update.html
View file @
3d18edc3
File moved
articles/templates/partial/pagination.html
0 → 100644
View file @
3d18edc3
<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"
>
«
В начало
</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 }}"
>
В конец
»
</a>
</span>
</div>
\ No newline at end of file
articles/urls.py
View file @
3d18edc3
from
django.urls
import
path
from
.views
import
(
article_list_v
iew
,
ArticleListV
iew
,
ArticleDetailView
,
CommentView
,
author_
list_view
,
author_edit_view
,
author_delete_view
,
AuthorView
,
CreateArticleView
,
ArticleUpdate
View
author_
edit_view
,
author_delete_view
,
AuthorView
,
CreateArticleView
,
ArticleUpdateView
,
AuthorList
View
)
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"
),
...
...
articles/views.py
View file @
3d18edc3
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
)
...
...
core/settings.py
View file @
3d18edc3
...
...
@@ -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'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment