Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django2-project-template
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django2-project-template
Commits
dbcf1c9d
Unverified
Kaydet (Commit)
dbcf1c9d
authored
Mar 21, 2019
tarafından
Uğur Özyılmazel
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
New release - version: 1.3.0
- Upgrade all python packages - Django 2.1.7 - Fix SoftDelete related objects
üst
57340eea
Hide whitespace changes
Inline
Side-by-side
Showing
47 changed files
with
274 additions
and
713 deletions
+274
-713
README.md
README.md
+14
-13
__init__.py
applications/baseapp/admin/__init__.py
+1
-0
base.py
applications/baseapp/admin/base.py
+16
-37
user.py
applications/baseapp/admin/user.py
+4
-18
__init__.py
applications/baseapp/forms/__init__.py
+4
-1
user.py
applications/baseapp/forms/user.py
+5
-16
base.py
applications/baseapp/management/base.py
+3
-6
create_app.py
applications/baseapp/management/commands/create_app.py
+21
-72
create_model.py
applications/baseapp/management/commands/create_model.py
+27
-80
__init__.py
...ations/baseapp/management/template_structures/__init__.py
+1
-0
__init__.py
...baseapp/management/template_structures/admins/__init__.py
+1
-0
__init__.py
...pp/management/template_structures/application/__init__.py
+1
-0
html.py
...aseapp/management/template_structures/application/html.py
+1
-2
__init__.py
...baseapp/management/template_structures/models/__init__.py
+1
-0
basemodel.py
...aseapp/management/template_structures/models/basemodel.py
+2
-9
django.py
...s/baseapp/management/template_structures/models/django.py
+4
-17
softdelete.py
...seapp/management/template_structures/models/softdelete.py
+2
-9
__init__.py
applications/baseapp/middlewares/__init__.py
+4
-1
locale.py
applications/baseapp/middlewares/locale.py
+1
-3
__init__.py
applications/baseapp/mixins/__init__.py
+4
-1
__init__.py
applications/baseapp/models/__init__.py
+1
-0
base.py
applications/baseapp/models/base.py
+27
-75
user.py
applications/baseapp/models/user.py
+17
-62
base_models.py
applications/baseapp/tests/base_models.py
+1
-3
test_basemodel.py
applications/baseapp/tests/test_basemodel.py
+9
-20
test_basemodelwithsoftdelete.py
applications/baseapp/tests/test_basemodelwithsoftdelete.py
+12
-39
__init__.py
applications/baseapp/utils/__init__.py
+1
-0
console.py
applications/baseapp/utils/console.py
+27
-91
upload_handler.py
applications/baseapp/utils/upload_handler.py
+4
-10
urlify.py
applications/baseapp/utils/urlify.py
+1
-6
__init__.py
applications/baseapp/views/__init__.py
+2
-0
index.py
applications/baseapp/views/index.py
+1
-5
__init__.py
applications/baseapp/widgets/__init__.py
+4
-1
base.py
config/settings/base.py
+1
-5
development.example.py
config/settings/development.example.py
+5
-22
heroku.py
config/settings/heroku.py
+10
-33
test.example.py
config/settings/test.example.py
+2
-9
travis.py
config/settings/travis.py
+2
-9
wsgi.py
config/wsgi.py
+1
-4
install.sh
install.sh
+10
-5
__init__.py
logging_helpers/__init__.py
+1
-0
formatters.py
logging_helpers/formatters.py
+3
-10
werkzueg_filters.py
logging_helpers/werkzueg_filters.py
+2
-7
pyproject.toml
pyproject.toml
+1
-1
base.pip
requirements/base.pip
+3
-3
development.pip
requirements/development.pip
+7
-7
heroku.pip
requirements/heroku.pip
+2
-1
No files found.
README.md
Dosyayı görüntüle @
dbcf1c9d
[
![Build Status
](
https://travis-ci.org/vigo/django2-project-template.svg?branch=master
)
](https://travis-ci.org/vigo/django2-project-template)
![
Python
](
https://img.shields.io/badge/django-3.7.0-green.svg
)
![
Django
](
https://img.shields.io/badge/django-2.1.
5
-green.svg
)
![
Version
](
https://img.shields.io/badge/version-1.
2
.0-yellow.svg
)
![
Django
](
https://img.shields.io/badge/django-2.1.
7
-green.svg
)
![
Version
](
https://img.shields.io/badge/version-1.
3
.0-yellow.svg
)
# Django Project Starter Template
...
...
@@ -524,9 +524,10 @@ need to create a copy of it! (*if you follow along from the beginning, you’ve
All the base/common required Python packages/modules are defined under `requirements/base.pip`
:
```
python
django-extensions==2.1.3
Django==2.1.7
Pillow==5.4.1
django-extensions==2.1.4
django-extensions==2.1.6
python-slugify==3.0.0
```
### `base.py`
...
...
@@ -645,14 +646,14 @@ All the required modules are defined under `requirements/development.pip`:
```
python
-r base.pip
ipython==7.
1.1
Werkzeug==0.1
4.1
ipython==7.
3.0
Werkzeug==0.1
5.0
django-debug-toolbar==1.11
coverage==4.5.
2
isort==4.3.
4
black==1
8.9
b0
flake8==3.
6.0
flake8-bandit==2.
0
.0
coverage==4.5.
3
isort==4.3.
15
black==1
9.3
b0
flake8==3.
7.7
flake8-bandit==2.
1
.0
flake8-blind-except==0.1.1
flake8-bugbear==18.8.0
flake8-builtins==1.4.1
...
...
@@ -660,7 +661,7 @@ flake8-polyfill==1.0.2
flake8-print==3.1.0
flake8-quotes==1.0.0
flake8-string-format==0.2.3
pylint==2.
2.2
pylint==2.
3.1
```
### `test.example.py`
...
...
@@ -693,7 +694,7 @@ All the required modules are defined under `requirements/heroku.pip`:
```
python
-r base.pip
gunicorn==19.9.0
psycopg2-binary==2.7.
6.1
psycopg2-binary==2.7.
7
dj-database-url==0.5.0
whitenoise==4.1.2
```
...
...
applications/baseapp/admin/__init__.py
Dosyayı görüntüle @
dbcf1c9d
# isort:skip_file
# flake8: noqa
from
.user
import
*
from
.base
import
*
applications/baseapp/admin/base.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -20,25 +20,21 @@ class BaseAdmin(admin.ModelAdmin):
def
get_list_filter
(
self
,
request
):
list_filter
=
list
(
super
()
.
get_list_filter
(
request
))
if
self
.
sticky_list_filter
:
list_filter
=
list
(
self
.
sticky_list_filter
)
+
list
(
list_filter
)
list_filter
=
list
(
self
.
sticky_list_filter
)
+
list
(
list_filter
)
return
list_filter
def
recover_selected
(
modeladmin
,
request
,
queryset
):
number_of_rows_recovered
,
recovered_items
=
(
queryset
.
undelete
()
)
number_of_rows_recovered
,
recovered_items
=
queryset
.
undelete
()
if
number_of_rows_recovered
==
1
:
message_bit
=
_
(
'1 record was'
)
else
:
message_bit
=
_
(
'
%(number_of_rows)
s records were'
)
%
dict
(
number_of_rows
=
number_of_rows_recovered
)
message
=
_
(
'
%(message_bit)
s successfully marked as active'
)
%
dict
(
message_bit
=
message_bit
)
message_bit
=
_
(
'
%(number_of_rows)
s records were'
)
%
dict
(
number_of_rows
=
number_of_rows_recovered
)
message
=
_
(
'
%(message_bit)
s successfully marked as active'
)
%
dict
(
message_bit
=
message_bit
)
modeladmin
.
message_user
(
request
,
message
)
return
None
...
...
@@ -55,28 +51,20 @@ def hard_delete_selected(modeladmin, request, queryset):
raise
PermissionDenied
n
=
queryset
.
count
()
if
n
:
number_of_rows_deleted
,
deleted_items
=
(
queryset
.
hard_delete
()
)
number_of_rows_deleted
,
deleted_items
=
queryset
.
hard_delete
()
if
number_of_rows_deleted
==
1
:
message_bit
=
_
(
'1 record was'
)
else
:
message_bit
=
_
(
'
%(number_of_rows)
s records were'
)
%
dict
(
message_bit
=
_
(
'
%(number_of_rows)
s records were'
)
%
dict
(
number_of_rows
=
number_of_rows_deleted
)
message
=
_
(
'
%(message_bit)
s deleted'
)
%
dict
(
message_bit
=
message_bit
)
message
=
_
(
'
%(message_bit)
s deleted'
)
%
dict
(
message_bit
=
message_bit
)
modeladmin
.
message_user
(
request
,
message
)
return
None
objects_name
=
model_ngettext
(
queryset
)
if
perms_needed
or
protected
:
title
=
_
(
'Cannot delete
%(name)
s'
)
%
{
'name'
:
objects_name
}
title
=
_
(
'Cannot delete
%(name)
s'
)
%
{
'name'
:
objects_name
}
else
:
title
=
_
(
'Are you sure?'
)
...
...
@@ -97,9 +85,7 @@ def hard_delete_selected(modeladmin, request, queryset):
request
.
current_app
=
modeladmin
.
admin_site
.
name
return
TemplateResponse
(
request
,
'admin/hard_delete_selected_confirmation.html'
,
context
,
request
,
'admin/hard_delete_selected_confirmation.html'
,
context
)
...
...
@@ -110,10 +96,7 @@ class BaseAdminWithSoftDelete(BaseAdmin):
def
get_queryset
(
self
,
request
):
qs
=
self
.
model
.
objects
.
get_queryset
()
if
request
.
GET
.
get
(
'status__exact'
,
None
):
if
(
numerify
(
request
.
GET
.
get
(
'status__exact'
))
==
BaseModel
.
STATUS_DELETED
):
if
numerify
(
request
.
GET
.
get
(
'status__exact'
))
==
BaseModel
.
STATUS_DELETED
:
return
qs
.
deleted
()
return
qs
.
all
()
...
...
@@ -131,9 +114,7 @@ class BaseAdminWithSoftDelete(BaseAdmin):
recover_selected
=
(
recover_selected
,
'recover_selected'
,
_
(
'Recover selected
%(verbose_name_plural)
s'
),
_
(
'Recover selected
%(verbose_name_plural)
s'
),
)
)
)
...
...
@@ -142,9 +123,7 @@ class BaseAdminWithSoftDelete(BaseAdmin):
hard_delete_selected
=
(
hard_delete_selected
,
'hard_delete_selected'
,
_
(
'Hard delete selected
%(verbose_name_plural)
s'
),
_
(
'Hard delete selected
%(verbose_name_plural)
s'
),
)
)
)
...
...
applications/baseapp/admin/user.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -18,19 +18,9 @@ class UserAdmin(BaseUserAdmin):
form
=
UserChangeForm
add_form
=
UserCreationForm
list_display
=
(
'user_profile_image'
,
'email'
,
'first_name'
,
'last_name'
,
)
list_display
=
(
'user_profile_image'
,
'email'
,
'first_name'
,
'last_name'
)
list_display_links
=
(
'email'
,)
search_fields
=
(
'email'
,
'first_name'
,
'middle_name'
,
'last_name'
,
)
search_fields
=
(
'email'
,
'first_name'
,
'middle_name'
,
'last_name'
)
ordering
=
(
'email'
,)
fieldsets
=
(
(
...
...
@@ -74,9 +64,7 @@ class UserAdmin(BaseUserAdmin):
},
),
)
formfield_overrides
=
{
models
.
FileField
:
{
'widget'
:
AdminImageFileWidget
}
}
formfield_overrides
=
{
models
.
FileField
:
{
'widget'
:
AdminImageFileWidget
}}
def
user_profile_image
(
self
,
obj
):
if
obj
.
avatar
:
...
...
@@ -88,9 +76,7 @@ class UserAdmin(BaseUserAdmin):
else
:
return
'---'
user_profile_image
.
short_description
=
_
(
'Profile Image'
)
user_profile_image
.
short_description
=
_
(
'Profile Image'
)
admin
.
site
.
register
(
User
,
UserAdmin
)
applications/baseapp/forms/__init__.py
Dosyayı görüntüle @
dbcf1c9d
from
.user
import
*
# noqa
# isort:skip_file
# flake8: noqa
from
.user
import
*
applications/baseapp/forms/user.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -43,12 +43,9 @@ class UserChangeForm(forms.ModelForm):
class
UserCreationForm
(
forms
.
ModelForm
):
password1
=
forms
.
CharField
(
label
=
_
(
'Password'
),
widget
=
forms
.
PasswordInput
)
password1
=
forms
.
CharField
(
label
=
_
(
'Password'
),
widget
=
forms
.
PasswordInput
)
password2
=
forms
.
CharField
(
label
=
_
(
'Password confirmation'
),
widget
=
forms
.
PasswordInput
,
label
=
_
(
'Password confirmation'
),
widget
=
forms
.
PasswordInput
)
class
Meta
:
...
...
@@ -66,20 +63,12 @@ class UserCreationForm(forms.ModelForm):
def
clean_password2
(
self
):
password1
=
self
.
cleaned_data
.
get
(
'password1'
)
password2
=
self
.
cleaned_data
.
get
(
'password2'
)
if
(
password1
and
password2
and
password1
!=
password2
):
raise
forms
.
ValidationError
(
_
(
'Passwords don
\'
t match'
)
)
if
password1
and
password2
and
password1
!=
password2
:
raise
forms
.
ValidationError
(
_
(
'Passwords don
\'
t match'
))
return
password2
def
save
(
self
,
commit
=
True
):
user
=
super
(
UserCreationForm
,
self
)
.
save
(
commit
=
False
)
user
=
super
(
UserCreationForm
,
self
)
.
save
(
commit
=
False
)
user
.
set_password
(
self
.
cleaned_data
[
'password1'
])
if
commit
:
user
.
save
()
...
...
applications/baseapp/management/base.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -3,11 +3,8 @@ from django.core.management.base import BaseCommand
class
CustomBaseCommand
(
BaseCommand
):
def
out
(
self
,
text
,
style
=
's'
):
switcher
=
{
's'
:
'SUCCESS'
,
'w'
:
'WARNING'
,
'e'
:
'ERROR'
,
'n'
:
'NOTICE'
,
}
.
get
(
style
,
's'
)
switcher
=
{
's'
:
'SUCCESS'
,
'w'
:
'WARNING'
,
'e'
:
'ERROR'
,
'n'
:
'NOTICE'
}
.
get
(
style
,
's'
)
writer
=
getattr
(
self
.
style
,
switcher
)
self
.
stdout
.
write
(
writer
(
text
))
applications/baseapp/management/commands/create_app.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -8,9 +8,7 @@ from django.core.management.base import CommandError
from
django.utils.text
import
capfirst
from
..base
import
CustomBaseCommand
from
..template_structures
import
(
application
as
application_templates
,
)
from
..template_structures
import
application
as
application_templates
TEMPLATE_MODELS_INIT
=
"""# isort:skip_file
# flake8: noqa
...
...
@@ -100,17 +98,10 @@ class Command(CustomBaseCommand):
'`applications/` directory.'
)
missing_args_message
=
(
'You must provide an application name.'
)
missing_args_message
=
'You must provide an application name.'
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'name'
,
nargs
=
1
,
type
=
str
,
help
=
'Name of your application'
,
)
parser
.
add_argument
(
'name'
,
nargs
=
1
,
type
=
str
,
help
=
'Name of your application'
)
def
handle
(
self
,
*
args
,
**
options
):
app_name
=
options
.
pop
(
'name'
)[
0
]
...
...
@@ -126,15 +117,9 @@ class Command(CustomBaseCommand):
%
app_name
# noqa: C812
)
applications_dir
=
os
.
path
.
join
(
settings
.
BASE_DIR
,
'applications'
)
templates_dir
=
os
.
path
.
join
(
settings
.
BASE_DIR
,
'templates'
)
new_application_dir
=
os
.
path
.
join
(
applications_dir
,
app_name
)
applications_dir
=
os
.
path
.
join
(
settings
.
BASE_DIR
,
'applications'
)
templates_dir
=
os
.
path
.
join
(
settings
.
BASE_DIR
,
'templates'
)
new_application_dir
=
os
.
path
.
join
(
applications_dir
,
app_name
)
render_params
=
dict
(
app_name_title
=
app_name
.
title
(),
...
...
@@ -143,75 +128,39 @@ class Command(CustomBaseCommand):
)
self
.
mkdir
(
new_application_dir
)
self
.
touch
(
os
.
path
.
join
(
new_application_dir
,
'__init__.py'
)
)
self
.
touch
(
os
.
path
.
join
(
new_application_dir
,
'__init__.py'
))
for
package
in
APP_DIR_STRUCTURE
.
get
(
'packages'
):
package_dir
=
os
.
path
.
join
(
new_application_dir
,
package
.
get
(
'name'
)
)
package_dir
=
os
.
path
.
join
(
new_application_dir
,
package
.
get
(
'name'
))
self
.
mkdir
(
package_dir
)
self
.
touch
(
os
.
path
.
join
(
package_dir
,
'__init__.py'
)
)
self
.
touch
(
os
.
path
.
join
(
package_dir
,
'__init__.py'
))
if
package
.
get
(
'files'
,
False
):
self
.
generate_files
(
package
.
get
(
'files'
),
package_dir
,
render_params
,
)
self
.
generate_files
(
package
.
get
(
'files'
),
package_dir
,
render_params
)
for
template
in
APP_DIR_STRUCTURE
.
get
(
'templates'
):
template_dir
=
os
.
path
.
join
(
templates_dir
,
app_name
)
template_html_path
=
os
.
path
.
join
(
template_dir
,
template
.
get
(
'name'
)
)
template_dir
=
os
.
path
.
join
(
templates_dir
,
app_name
)
template_html_path
=
os
.
path
.
join
(
template_dir
,
template
.
get
(
'name'
))
self
.
mkdir
(
template_dir
)
self
.
touch
(
template_html_path
)
if
template
.
get
(
'render'
,
False
):
rendered_content
=
template
.
get
(
'render'
)
.
format
(
**
render_params
)
self
.
create_file_with_content
(
template_html_path
,
rendered_content
)
rendered_content
=
template
.
get
(
'render'
)
.
format
(
**
render_params
)
self
.
create_file_with_content
(
template_html_path
,
rendered_content
)
self
.
generate_files
(
APP_DIR_STRUCTURE
.
get
(
'files'
),
new_application_dir
,
render_params
,
APP_DIR_STRUCTURE
.
get
(
'files'
),
new_application_dir
,
render_params
)
self
.
stdout
.
write
(
self
.
style
.
SUCCESS
(
'"{0}" application created.'
.
format
(
app_name
)
)
)
self
.
stdout
.
write
(
self
.
style
.
NOTICE
(
USER_REMINDER
.
format
(
app_name
=
app_name
)
)
self
.
style
.
SUCCESS
(
'"{0}" application created.'
.
format
(
app_name
))
)
self
.
stdout
.
write
(
self
.
style
.
NOTICE
(
USER_REMINDER
.
format
(
app_name
=
app_name
)))
def
generate_files
(
self
,
files_list
,
root_path
,
render_params
):
def
generate_files
(
self
,
files_list
,
root_path
,
render_params
):
for
single_file
in
files_list
:
file_path
=
os
.
path
.
join
(
root_path
,
single_file
.
get
(
'name'
)
)
file_path
=
os
.
path
.
join
(
root_path
,
single_file
.
get
(
'name'
))
self
.
touch
(
file_path
)
if
single_file
.
get
(
'render'
,
False
):
rendered_content
=
single_file
.
get
(
'render'
)
.
format
(
**
render_params
)
self
.
create_file_with_content
(
file_path
,
rendered_content
)
rendered_content
=
single_file
.
get
(
'render'
)
.
format
(
**
render_params
)
self
.
create_file_with_content
(
file_path
,
rendered_content
)
def
mkdir
(
self
,
dirname
):
try
:
...
...
applications/baseapp/management/commands/create_model.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -43,31 +43,17 @@ USER_REMINDER = """
class
Command
(
BaseCommand
):
help
=
'Creates models/MODEL.py, admin/MODEL.py for given application'
# noqa: A003
MODEL_TYPE_CHOISES
=
[
'django'
,
'basemodel'
,
'softdelete'
,
]
def
create_or_modify_file
(
self
,
filename
,
content
,
mode
=
'w'
):
MODEL_TYPE_CHOISES
=
[
'django'
,
'basemodel'
,
'softdelete'
]
def
create_or_modify_file
(
self
,
filename
,
content
,
mode
=
'w'
):
with
open
(
filename
,
mode
)
as
f
:
f
.
write
(
content
)
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'app_name'
,
nargs
=
1
,
type
=
str
,
help
=
'Name of your application'
,
)
parser
.
add_argument
(
'model_name'
,
nargs
=
1
,
type
=
str
,
help
=
'Name of your model'
,
'app_name'
,
nargs
=
1
,
type
=
str
,
help
=
'Name of your application'
)
parser
.
add_argument
(
'model_name'
,
nargs
=
1
,
type
=
str
,
help
=
'Name of your model'
)
parser
.
add_argument
(
'model_type'
,
nargs
=
'?'
,
...
...
@@ -85,109 +71,70 @@ class Command(BaseCommand):
import_module
(
app_name
)
except
ImportError
:
raise
CommandError
(
'
%
s is not exists. Please pass existing application name.'
%
app_name
'
%
s is not exists. Please pass existing application name.'
%
app_name
)
if
model_name
.
lower
()
in
[
model
.
__name__
.
lower
()
for
model
in
apps
.
get_app_config
(
app_name
)
.
get_models
()
for
model
in
apps
.
get_app_config
(
app_name
)
.
get_models
()
]:
raise
CommandError
(
'
%
s model is already exists in
%
s. Please try non-existing model name.'
%
(
model_name
,
app_name
)
)
app_dir
=
os
.
path
.
join
(
settings
.
BASE_DIR
,
'applications'
,
app_name
)
app_dir
=
os
.
path
.
join
(
settings
.
BASE_DIR
,
'applications'
,
app_name
)
dash_seperated_file_base_name
=
'_'
.
join
(
[
m
for
m
in
re
.
split
(
'([A-Z][a-z]+)'
,
model_name
)
if
m
]
[
m
for
m
in
re
.
split
(
'([A-Z][a-z]+)'
,
model_name
)
if
m
]
)
model_file
=
os
.
path
.
join
(
app_dir
,
'models'
,
'{0}.py'
.
format
(
dash_seperated_file_base_name
.
lower
()
),
)
model_init_file
=
os
.
path
.
join
(
app_dir
,
'models'
,
'__init__.py'
app_dir
,
'models'
,
'{0}.py'
.
format
(
dash_seperated_file_base_name
.
lower
())
)
model_init_file
=
os
.
path
.
join
(
app_dir
,
'models'
,
'__init__.py'
)
admin_file
=
os
.
path
.
join
(
app_dir
,
'admin'
,
'{0}.py'
.
format
(
dash_seperated_file_base_name
.
lower
()
),
)
admin_init_file
=
os
.
path
.
join
(
app_dir
,
'admin'
,
'__init__.py'
app_dir
,
'admin'
,
'{0}.py'
.
format
(
dash_seperated_file_base_name
.
lower
())
)
admin_init_file
=
os
.
path
.
join
(
app_dir
,
'admin'
,
'__init__.py'
)
content_model_file
=
TEMPLATE_MODELS
[
model_
typ
e
]
.
format
(
model_name
=
model_name
,
app_name
=
app_name
)
content_model_file
=
TEMPLATE_MODELS
[
model_type
]
.
format
(
model_
name
=
model_name
,
app_name
=
app_nam
e
)
content_init_file
=
'from .{0} import *
\n
'
.
format
(
dash_seperated_file_base_name
.
lower
()
)
content_admin_file
=
TEMPLATE_ADMINS
[
model_type
]
.
format
(
model_name
=
model_name
,
app_name
=
app_name
)
self
.
create_or_modify_file
(
model_file
,
content_model_file
content_admin_file
=
TEMPLATE_ADMINS
[
model_type
]
.
format
(
model_name
=
model_name
,
app_name
=
app_name
)
self
.
create_or_modify_file
(
model_file
,
content_model_file
)
self
.
stdout
.
write
(
self
.
style
.
SUCCESS
(
'models/{0} created.'
.
format
(
os
.
path
.
basename
(
model_file
)
)
'models/{0} created.'
.
format
(
os
.
path
.
basename
(
model_file
))
)
)
self
.
create_or_modify_file
(
admin_file
,
content_admin_file
)
self
.
create_or_modify_file
(
admin_file
,
content_admin_file
)
self
.
stdout
.
write
(
self
.
style
.
SUCCESS
(
'admin/{0} created.'
.
format
(
os
.
path
.
basename
(
admin_file
)
)
'admin/{0} created.'
.
format
(
os
.
path
.
basename
(
admin_file
))
)
)
self
.
create_or_modify_file
(
model_init_file
,
content_init_file
,
'a'
)
self
.
create_or_modify_file
(
model_init_file
,
content_init_file
,
'a'
)
self
.
stdout
.
write
(
self
.
style
.
SUCCESS
(
'{0} model added to models/__init__.py'
.
format
(
model_name
)
'{0} model added to models/__init__.py'
.
format
(
model_name
)
)
)
self
.
create_or_modify_file
(
admin_init_file
,
content_init_file
,
'a'
)
self
.
create_or_modify_file
(
admin_init_file
,
content_init_file
,
'a'
)
self
.
stdout
.
write
(
self
.
style
.
SUCCESS
(
'{0} model added to admin/__init__.py'
.
format
(
model_name
)
'{0} model added to admin/__init__.py'
.
format
(
model_name
)
)
)
...
...
applications/baseapp/management/template_structures/__init__.py
Dosyayı görüntüle @
dbcf1c9d
# isort:skip_file
# flake8: noqa
from
.models
import
*
from
.admins
import
*
applications/baseapp/management/template_structures/admins/__init__.py
Dosyayı görüntüle @
dbcf1c9d
# isort:skip_file
# flake8: noqa
from
.basemodel
import
*
from
.django
import
*
from
.softdelete
import
*
applications/baseapp/management/template_structures/application/__init__.py
Dosyayı görüntüle @
dbcf1c9d
# isort:skip_file
# flake8: noqa
from
.html
import
*
from
.apps
import
*
from
.urls
import
*
...
...
applications/baseapp/management/template_structures/application/html.py
Dosyayı görüntüle @
dbcf1c9d
TEMPLATE_HTML
=
"""{{
%
extends "base.html"
%
}}
{{
%
load static
%
}}
{{
%
load i18n
%
}}
{{
%
load static i18n
%
}}
{{
%
block title
%
}}{app_name_title} Application{{
%
endblock
%
}}
...
...
applications/baseapp/management/template_structures/models/__init__.py
Dosyayı görüntüle @
dbcf1c9d
# isort:skip_file
# flake8: noqa
from
.basemodel
import
*
from
.django
import
*
from
.softdelete
import
*
applications/baseapp/management/template_structures/models/basemodel.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -3,17 +3,11 @@ from django.utils.translation import ugettext_lazy as _
from baseapp.models import BaseModel
# fmt: off
__all__ = [
'{model_name}',
]
__all__ = ['{model_name}']
class {model_name}(BaseModel):
title = models.CharField(
max_length=255,
verbose_name=_('title'),
)
title = models.CharField(max_length=255, verbose_name=_('title'))
class Meta:
app_label = '{app_name}'
...
...
@@ -22,7 +16,6 @@ class {model_name}(BaseModel):
def __str__(self):
return self.title
# fmt: on
"""
...
...
applications/baseapp/management/template_structures/models/django.py
Dosyayı görüntüle @
dbcf1c9d
TEMPLATE_MODEL_DJANGO
=
"""from django.db import models
from django.utils.translation import ugettext_lazy as _
# fmt: off
__all__ = [
'{model_name}',
]
__all__ = ['{model_name}']
class {model_name}(models.Model):
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name=_('Created At'),
)
updated_at = models.DateTimeField(
auto_now=True,
verbose_name=_('Updated At'),
)
title = models.CharField(
max_length=255,
verbose_name=_('title'),
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('created at'))
updated_at = models.DateTimeField(auto_now=True, verbose_name=_('updated at'))
title = models.CharField(max_length=255, verbose_name=_('title'))
class Meta:
app_label = '{app_name}'
...
...
@@ -28,7 +16,6 @@ class {model_name}(models.Model):
def __str__(self):
return self.title
# fmt: on
"""
...
...
applications/baseapp/management/template_structures/models/softdelete.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -3,17 +3,11 @@ from django.utils.translation import ugettext_lazy as _
from baseapp.models import BaseModelWithSoftDelete
# fmt: off
__all__ = [
'{model_name}',
]
__all__ = ['{model_name}']
class {model_name}(BaseModelWithSoftDelete):
title = models.CharField(
max_length=255,
verbose_name=_('title'),
)
title = models.CharField(max_length=255, verbose_name=_('title'))
class Meta:
app_label = '{app_name}'
...
...
@@ -22,7 +16,6 @@ class {model_name}(BaseModelWithSoftDelete):
def __str__(self):
return self.title
# fmt: on
"""
...
...
applications/baseapp/middlewares/__init__.py
Dosyayı görüntüle @
dbcf1c9d
from
.locale
import
*
# noqa
# isort:skip_file
# flake8: noqa
from
.locale
import
*
applications/baseapp/middlewares/locale.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -34,8 +34,6 @@ class CustomLocaleMiddleware(object):
response
=
self
.
get_response
(
request
)
patch_vary_headers
(
response
,
(
'Accept-Language'
,))
response
[
'Content-Language'
]
=
translation
.
get_language
()
response
[
'Content-Language'
]
=
translation
.
get_language
()
translation
.
deactivate
()
return
response
applications/baseapp/mixins/__init__.py
Dosyayı görüntüle @
dbcf1c9d
from
.html_debug
import
*
# noqa
# isort:skip_file
# flake8: noqa
from
.html_debug
import
*
applications/baseapp/models/__init__.py
Dosyayı görüntüle @
dbcf1c9d
# isort:skip_file
# flake8: noqa
from
.base
import
*
from
.user
import
*
applications/baseapp/models/base.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -60,19 +60,13 @@ class BaseModelWithSoftDeleteQuerySet(BaseModelQuerySet):
)
def
actives
(
self
):
return
self
.
all
()
.
filter
(
status
=
BaseModel
.
STATUS_ONLINE
)
return
self
.
all
()
.
filter
(
status
=
BaseModel
.
STATUS_ONLINE
)
def
offlines
(
self
):
return
self
.
all
()
.
filter
(
status
=
BaseModel
.
STATUS_OFFLINE
)
return
self
.
all
()
.
filter
(
status
=
BaseModel
.
STATUS_OFFLINE
)
def
drafts
(
self
):
return
self
.
all
()
.
filter
(
status
=
BaseModel
.
STATUS_DRAFT
)
return
self
.
all
()
.
filter
(
status
=
BaseModel
.
STATUS_DRAFT
)
def
delete
(
self
):
return
self
.
_delete_or_undelete
()
...
...
@@ -88,22 +82,13 @@ class BaseModelWithSoftDeleteQuerySet(BaseModelQuerySet):
call_method
=
'undelete'
if
undelete
else
'delete'
for
model_instance
in
self
:
_count
,
model_information
=
getattr
(
model_instance
,
call_method
)()
for
(
app_label
,
row_amount
,
)
in
model_information
.
items
():
_count
,
model_information
=
getattr
(
model_instance
,
call_method
)()
for
(
app_label
,
row_amount
)
in
model_information
.
items
():
processed_instances
.
setdefault
(
app_label
,
0
)
processed_instances
[
app_label
]
=
(
processed_instances
[
app_label
]
+
row_amount
processed_instances
[
app_label
]
+
row_amount
)
return
(
sum
(
processed_instances
.
values
()),
processed_instances
,
)
return
(
sum
(
processed_instances
.
values
()),
processed_instances
)
class
BaseModelManager
(
models
.
Manager
):
...
...
@@ -129,9 +114,7 @@ class BaseModelWithSoftDeleteManager(BaseModelManager):
"""
def
get_queryset
(
self
):
return
BaseModelWithSoftDeleteQuerySet
(
self
.
model
,
using
=
self
.
_db
)
return
BaseModelWithSoftDeleteQuerySet
(
self
.
model
,
using
=
self
.
_db
)
def
all
(
self
):
# noqa: A003
return
self
.
get_queryset
()
.
all
()
...
...
@@ -163,16 +146,10 @@ class BaseModel(models.Model):
(
STATUS_DRAFT
,
_
(
'Draft'
)),
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Created At'
)
)
updated_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'Updated At'
)
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Created At'
))
updated_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'Updated At'
))
status
=
models
.
IntegerField
(
choices
=
STATUS_CHOICES
,
default
=
STATUS_ONLINE
,
verbose_name
=
_
(
'Status'
),
choices
=
STATUS_CHOICES
,
default
=
STATUS_ONLINE
,
verbose_name
=
_
(
'Status'
)
)
objects
=
BaseModelManager
()
...
...
@@ -205,19 +182,11 @@ class BaseModelWithSoftDelete(BaseModel):
processed_instances
=
{}
call_method
=
'undelete'
if
undelete
else
'delete'
log_params
=
{
'instance'
:
self
,
'label'
:
self
.
_meta
.
label
,
'pk'
:
self
.
pk
,
}
log_message
=
(
'{action} on: "{instance} - pk: {pk}" [{label}]'
)
log_params
=
{
'instance'
:
self
,
'label'
:
self
.
_meta
.
label
,
'pk'
:
self
.
pk
}
log_message
=
'{action} on: "{instance} - pk: {pk}" [{label}]'
if
call_method
==
'delete'
:
models
.
signals
.
pre_delete
.
send
(
sender
=
self
.
__class__
,
instance
=
self
)
models
.
signals
.
pre_delete
.
send
(
sender
=
self
.
__class__
,
instance
=
self
)
status_value
=
self
.
STATUS_DELETED
deleted_at_value
=
timezone
.
now
()
log_params
.
update
(
action
=
'Soft-delete'
)
...
...
@@ -233,43 +202,29 @@ class BaseModelWithSoftDelete(BaseModel):
self
.
save
()
if
call_method
==
'delete'
:
models
.
signals
.
post_delete
.
send
(
sender
=
self
.
__class__
,
instance
=
self
)
models
.
signals
.
post_delete
.
send
(
sender
=
self
.
__class__
,
instance
=
self
)
processed_instances
.
update
({
self
.
_meta
.
label
:
1
})
for
related_object
in
self
.
_meta
.
related_objects
:
if
(
hasattr
(
related_object
,
'on_delete'
)
and
getattr
(
related_object
,
'on_delete'
)
==
models
.
CASCADE
and
getattr
(
related_object
,
'on_delete'
)
==
models
.
CASCADE
):
accessor_name
=
(
related_object
.
get_accessor_name
()
)
related_model_instances
=
getattr
(
self
,
accessor_name
)
accessor_name
=
related_object
.
get_accessor_name
()
related_model_instances
=
getattr
(
self
,
accessor_name
)
related_model_instance_count
=
0
related_model_query
=
(
related_model_instances
.
all
()
)
if
call_method
==
'undelete'
:
related_model_query
=
(
related_model_instances
.
deleted
()
)
related_model_query
=
related_model_instances
.
all
()
if
call_method
==
'undelete'
and
hasattr
(
related_model_instances
,
'deleted'
):
related_model_query
=
related_model_instances
.
deleted
()
for
(
related_model_instance
)
in
related_model_query
:
getattr
(
related_model_instance
,
call_method
)()
for
related_model_instance
in
related_model_query
:
getattr
(
related_model_instance
,
call_method
)()
processed_instances
.
setdefault
(
related_model_instance
.
_meta
.
label
,
related_model_instance_count
,
related_model_instance
.
_meta
.
label
,
related_model_instance_count
)
related_model_instance_count
+=
1
processed_instances
.
update
(
...
...
@@ -277,7 +232,4 @@ class BaseModelWithSoftDelete(BaseModel):
related_model_instance
.
_meta
.
label
:
related_model_instance_count
}
)
return
(
sum
(
processed_instances
.
values
()),
processed_instances
,
)
return
(
sum
(
processed_instances
.
values
()),
processed_instances
)
applications/baseapp/models/user.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -23,17 +23,10 @@ class UserManager(BaseUserManager):
use_in_migrations
=
True
def
create_user
(
self
,
email
,
first_name
,
last_name
,
middle_name
=
None
,
password
=
None
,
self
,
email
,
first_name
,
last_name
,
middle_name
=
None
,
password
=
None
):
if
not
email
:
raise
ValueError
(
_
(
'Users must have an email address'
)
)
raise
ValueError
(
_
(
'Users must have an email address'
))
user_create_fields
=
{
'email'
:
email
,
...
...
@@ -47,39 +40,22 @@ class UserManager(BaseUserManager):
user
=
self
.
model
(
**
user_create_fields
)
user
.
set_password
(
password
)
user
.
save
(
using
=
self
.
_db
)
logger
.
info
(
f
'{user.get_full_name()} created successfully. PK: {user.pk}'
)
logger
.
info
(
f
'{user.get_full_name()} created successfully. PK: {user.pk}'
)
return
user
def
create_superuser
(
self
,
email
,
first_name
,
last_name
,
middle_name
=
None
,
password
=
None
,
self
,
email
,
first_name
,
last_name
,
middle_name
=
None
,
password
=
None
):
user
=
self
.
create_user
(
email
,
first_name
,
last_name
,
middle_name
,
password
,
)
user
=
self
.
create_user
(
email
,
first_name
,
last_name
,
middle_name
,
password
)
user
.
is_staff
=
True
user
.
is_superuser
=
True
user
.
save
(
using
=
self
.
_db
)
logger
.
info
(
f
'{user.get_full_name()} is set to superuser. PK: {user.pk}'
)
logger
.
info
(
f
'{user.get_full_name()} is set to superuser. PK: {user.pk}'
)
return
user
def
save_user_avatar
(
instance
,
filename
):
return
custom_save_file
(
instance
,
filename
,
upload_to
=
'avatar/'
)
return
custom_save_file
(
instance
,
filename
,
upload_to
=
'avatar/'
)
class
User
(
AbstractBaseUser
,
PermissionsMixin
):
...
...
@@ -87,39 +63,22 @@ class User(AbstractBaseUser, PermissionsMixin):
USERNAME_FIELD
=
'email'
REQUIRED_FIELDS
=
[
'first_name'
,
'last_name'
]
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Created At'
)
)
updated_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'Updated At'
)
)
email
=
models
.
EmailField
(
unique
=
True
,
verbose_name
=
_
(
'email address'
)
)
first_name
=
models
.
CharField
(
max_length
=
255
,
verbose_name
=
_
(
'first name'
)
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Created At'
))
updated_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'Updated At'
))
email
=
models
.
EmailField
(
unique
=
True
,
verbose_name
=
_
(
'email address'
))
first_name
=
models
.
CharField
(
max_length
=
255
,
verbose_name
=
_
(
'first name'
))
middle_name
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'middle name'
),
)
last_name
=
models
.
CharField
(
max_length
=
255
,
verbose_name
=
_
(
'last name'
)
max_length
=
255
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'middle name'
)
)
last_name
=
models
.
CharField
(
max_length
=
255
,
verbose_name
=
_
(
'last name'
))
avatar
=
models
.
FileField
(
upload_to
=
save_user_avatar
,
verbose_name
=
_
(
'Profile Image'
),
null
=
True
,
blank
=
True
,
)
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'active'
)
)
is_staff
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'staff status'
)
)
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'active'
))
is_staff
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'staff status'
))
objects
=
UserManager
()
...
...
@@ -141,12 +100,8 @@ class User(AbstractBaseUser, PermissionsMixin):
'last_name'
:
self
.
last_name
,
}
if
self
.
middle_name
:
params
[
'middle_name'
]
=
' {middle_name} '
.
format
(
params
[
'middle_name'
]
=
' {middle_name} '
.
format
(
middle_name
=
self
.
middle_name
)
full_name
=
'{first_name}{middle_name}{last_name}'
.
format
(
**
params
)
full_name
=
'{first_name}{middle_name}{last_name}'
.
format
(
**
params
)
return
full_name
.
strip
()
applications/baseapp/tests/base_models.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -25,9 +25,7 @@ class Category(BaseModelWithSoftDelete):
class
Post
(
BaseModelWithSoftDelete
):
category
=
models
.
ForeignKey
(
to
=
'Category'
,
on_delete
=
models
.
CASCADE
,
related_name
=
'posts'
,
to
=
'Category'
,
on_delete
=
models
.
CASCADE
,
related_name
=
'posts'
)
title
=
models
.
CharField
(
max_length
=
255
)
...
...
applications/baseapp/tests/test_basemodel.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -6,27 +6,20 @@ from .base_models import BasicPost
class
BaseModelTestCase
(
TestCase
):
@classmethod
def
setUpTestData
(
cls
):
# noqa: N802
cls
.
post
=
BasicPost
.
objects
.
create
(
title
=
'Test Post 1'
)
cls
.
post
=
BasicPost
.
objects
.
create
(
title
=
'Test Post 1'
)
cls
.
post_status_deleted
=
BasicPost
.
objects
.
create
(
title
=
'Test Post 2'
,
status
=
BasicPost
.
STATUS_DELETED
,
title
=
'Test Post 2'
,
status
=
BasicPost
.
STATUS_DELETED
)
cls
.
post_status_offline
=
BasicPost
.
objects
.
create
(
title
=
'Test Post 3'
,
status
=
BasicPost
.
STATUS_OFFLINE
,
title
=
'Test Post 3'
,
status
=
BasicPost
.
STATUS_OFFLINE
)
cls
.
post_status_draft
=
BasicPost
.
objects
.
create
(
title
=
'Test Post 4'
,
status
=
BasicPost
.
STATUS_DRAFT
,
title
=
'Test Post 4'
,
status
=
BasicPost
.
STATUS_DRAFT
)
def
test_basemodel_fields
(
self
):
self
.
assertEqual
(
self
.
post
.
pk
,
self
.
post
.
id
)
self
.
assertEqual
(
self
.
post
.
status
,
BasicPost
.
STATUS_ONLINE
)
self
.
assertEqual
(
self
.
post
.
status
,
BasicPost
.
STATUS_ONLINE
)
def
test_basemodel_queryset
(
self
):
self
.
assertQuerysetEqual
(
...
...
@@ -39,18 +32,14 @@ class BaseModelTestCase(TestCase):
],
)
self
.
assertQuerysetEqual
(
BasicPost
.
objects
.
actives
()
.
order_by
(
'id'
),
[
'<BasicPost: Test Post 1>'
],
BasicPost
.
objects
.
actives
()
.
order_by
(
'id'
),
[
'<BasicPost: Test Post 1>'
]
)
self
.
assertQuerysetEqual
(
BasicPost
.
objects
.
offlines
(),
[
'<BasicPost: Test Post 3>'
],
BasicPost
.
objects
.
offlines
(),
[
'<BasicPost: Test Post 3>'
]
)
self
.
assertQuerysetEqual
(
BasicPost
.
objects
.
deleted
(),
[
'<BasicPost: Test Post 2>'
],
BasicPost
.
objects
.
deleted
(),
[
'<BasicPost: Test Post 2>'
]
)
self
.
assertQuerysetEqual
(
BasicPost
.
objects
.
drafts
(),
[
'<BasicPost: Test Post 4>'
],
BasicPost
.
objects
.
drafts
(),
[
'<BasicPost: Test Post 4>'
]
)
applications/baseapp/tests/test_basemodelwithsoftdelete.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -9,60 +9,33 @@ class BaseModelWithSoftDeleteTestCase(TestCase):
category
=
Category
.
objects
.
create
(
title
=
'Python'
)
cls
.
category
=
category
cls
.
posts
=
[
Post
.
objects
.
create
(
category
=
category
,
title
=
'Python post 1'
),
Post
.
objects
.
create
(
category
=
category
,
title
=
'Python post 2'
),
Post
.
objects
.
create
(
category
=
category
,
title
=
'Python post 1'
),
Post
.
objects
.
create
(
category
=
category
,
title
=
'Python post 2'
),
]
def
test_basemodelwithsoftdelete_fields
(
self
):
self
.
assertEqual
(
self
.
category
.
pk
,
self
.
category
.
id
)
self
.
assertEqual
(
self
.
category
.
status
,
Post
.
STATUS_ONLINE
)
self
.
assertEqual
(
self
.
category
.
status
,
Post
.
STATUS_ONLINE
)
for
post
in
self
.
posts
:
self
.
assertEqual
(
post
.
status
,
Post
.
STATUS_ONLINE
)
self
.
assertEqual
(
post
.
status
,
Post
.
STATUS_ONLINE
)
def
test_basemodelwithsoftdelete_queryset
(
self
):
self
.
assertQuerysetEqual
(
self
.
category
.
posts
.
all
()
.
order_by
(
'id'
),
[
'<Post: Python post 1>'
,
'<Post: Python post 2>'
,
],
)
self
.
assertQuerysetEqual
(
Category
.
objects
.
actives
(),
[
'<Category: Python>'
],
)
self
.
assertQuerysetEqual
(
Category
.
objects
.
offlines
(),
[]
)
self
.
assertQuerysetEqual
(
Category
.
objects
.
deleted
(),
[]
)
self
.
assertQuerysetEqual
(
Category
.
objects
.
drafts
(),
[]
[
'<Post: Python post 1>'
,
'<Post: Python post 2>'
],
)
self
.
assertQuerysetEqual
(
Category
.
objects
.
actives
(),
[
'<Category: Python>'
])
self
.
assertQuerysetEqual
(
Category
.
objects
.
offlines
(),
[])
self
.
assertQuerysetEqual
(
Category
.
objects
.
deleted
(),
[])
self
.
assertQuerysetEqual
(
Category
.
objects
.
drafts
(),
[])
def
test_softdelete
(
self
):
deleted_category
=
self
.
category
.
delete
()
self
.
assertEqual
(
deleted_category
,
(
3
,
{
'baseapp.Category'
:
1
,
'baseapp.Post'
:
2
}),
)
self
.
assertQuerysetEqual
(
Category
.
objects
.
deleted
(),
[
'<Category: Python>'
],
deleted_category
,
(
3
,
{
'baseapp.Category'
:
1
,
'baseapp.Post'
:
2
})
)
self
.
assertQuerysetEqual
(
Category
.
objects
.
deleted
(),
[
'<Category: Python>'
])
self
.
assertQuerysetEqual
(
Post
.
objects
.
deleted
()
.
order_by
(
'id'
),
[
'<Post: Python post 1>'
,
'<Post: Python post 2>'
,
],
[
'<Post: Python post 1>'
,
'<Post: Python post 2>'
],
)
applications/baseapp/utils/__init__.py
Dosyayı görüntüle @
dbcf1c9d
# isort:skip_file
# flake8: noqa
from
.console
import
*
from
.numerify
import
*
from
.urlify
import
*
...
...
applications/baseapp/utils/console.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -11,9 +11,7 @@ try:
except
BaseException
:
pass
TERMINAL_COLUMNS
,
TERMINAL_LINES
=
(
shutil
.
get_terminal_size
()
)
TERMINAL_COLUMNS
,
TERMINAL_LINES
=
shutil
.
get_terminal_size
()
__all__
=
[
'console'
]
...
...
@@ -83,15 +81,7 @@ class Console:
valid_options
=
[
'source'
,
'width'
,
'indent'
,
'color'
]
available_colors
=
dict
(
black
=
0
,
red
=
1
,
green
=
2
,
yellow
=
3
,
blue
=
4
,
magenta
=
5
,
cyan
=
6
,
white
=
7
,
default
=
8
,
black
=
0
,
red
=
1
,
green
=
2
,
yellow
=
3
,
blue
=
4
,
magenta
=
5
,
cyan
=
6
,
white
=
7
,
default
=
8
)
defaults_options
=
{
...
...
@@ -106,10 +96,7 @@ class Console:
def
__init__
(
self
,
**
options
):
self
.
options
=
{}
for
(
default_option
,
default_value
,
)
in
self
.
defaults_options
.
items
():
for
(
default_option
,
default_value
)
in
self
.
defaults_options
.
items
():
self
.
options
[
default_option
]
=
default_value
self
.
configure
(
**
options
)
...
...
@@ -118,15 +105,11 @@ class Console:
if
option
in
self
.
valid_options
:
self
.
options
[
option
]
=
value
else
:
raise
Exception
(
f
'Invalid option: [{option}] passed'
)
raise
Exception
(
f
'Invalid option: [{option}] passed'
)
color
=
self
.
options
[
'color'
]
if
color
not
in
self
.
available_colors
.
keys
():
raise
Exception
(
f
'Invalid color value: [{color}] passed'
)
raise
Exception
(
f
'Invalid color value: [{color}] passed'
)
if
not
isinstance
(
self
.
options
[
'width'
],
int
):
raise
Exception
(
...
...
@@ -144,9 +127,7 @@ class Console:
def
colorize
(
self
,
input_string
):
return
'
\033
[3{0}m{1}{2}'
.
format
(
self
.
available_colors
[
self
.
options
[
'color'
]],
input_string
,
'
\033
[0m'
,
self
.
available_colors
[
self
.
options
[
'color'
]],
input_string
,
'
\033
[0m'
)
def
__call__
(
self
,
*
args
,
**
options
):
...
...
@@ -159,16 +140,12 @@ class Console:
source_name
=
arg
.
__class__
.
__name__
if
source_name
!=
'type'
:
source_name
=
'instance of {0}'
.
format
(
source_name
)
source_name
=
'instance of {0}'
.
format
(
source_name
)
if
hasattr
(
arg
,
'__name__'
):
source_name
=
arg
.
__name__
source
=
'{0} | {1}'
.
format
(
source_name
,
type
(
arg
)
)
source
=
'{0} | {1}'
.
format
(
source_name
,
type
(
arg
))
public_attributes
=
[]
internal_methods
=
[]
...
...
@@ -183,13 +160,9 @@ class Console:
public_attributes
.
append
(
object_method
)
if
public_attributes
:
out
.
update
(
public_attributes
=
public_attributes
)
out
.
update
(
public_attributes
=
public_attributes
)
if
internal_methods
:
out
.
update
(
internal_methods
=
internal_methods
)
out
.
update
(
internal_methods
=
internal_methods
)
if
private_methods
:
out
.
update
(
private_methods
=
private_methods
)
...
...
@@ -199,79 +172,49 @@ class Console:
class_methods
=
[]
public_methods
=
[]
for
(
obj_attr
,
obj_attr_val
,
)
in
arg
.
__dict__
.
items
():
for
(
obj_attr
,
obj_attr_val
)
in
arg
.
__dict__
.
items
():
_name
=
type
(
obj_attr_val
)
.
__name__
if
_name
==
'property'
:
property_list
.
append
(
obj_attr
)
if
obj_attr
in
public_attributes
:
public_attributes
.
remove
(
obj_attr
)
public_attributes
.
remove
(
obj_attr
)
if
_name
==
'staticmethod'
:
static_methods
.
append
(
obj_attr
)
if
obj_attr
in
public_attributes
:
public_attributes
.
remove
(
obj_attr
)
public_attributes
.
remove
(
obj_attr
)
if
_name
==
'classmethod'
:
class_methods
.
append
(
obj_attr
)
if
obj_attr
in
public_attributes
:
public_attributes
.
remove
(
obj_attr
)
public_attributes
.
remove
(
obj_attr
)
if
_name
==
'function'
:
public_methods
.
append
(
obj_attr
)
if
obj_attr
in
internal_methods
:
internal_methods
.
remove
(
obj_attr
)
internal_methods
.
remove
(
obj_attr
)
if
obj_attr
in
public_attributes
:
public_attributes
.
remove
(
obj_attr
)
public_attributes
.
remove
(
obj_attr
)
if
property_list
:
out
.
update
(
property_list
=
property_list
)
if
static_methods
:
out
.
update
(
static_methods
=
static_methods
)
out
.
update
(
static_methods
=
static_methods
)
if
class_methods
:
out
.
update
(
class_methods
=
class_methods
)
if
public_methods
:
out
.
update
(
public_methods
=
public_methods
)
out
.
update
(
public_methods
=
public_methods
)
if
not
arg
.
__dict__
.
get
(
'__init__'
,
False
):
instance_attributes
=
[]
for
instance_attr
in
list
(
arg
.
__dict__
.
keys
()
):
instance_attributes
.
append
(
instance_attr
)
if
(
instance_attr
in
public_attributes
):
public_attributes
.
remove
(
instance_attr
)
for
instance_attr
in
list
(
arg
.
__dict__
.
keys
()):
instance_attributes
.
append
(
instance_attr
)
if
instance_attr
in
public_attributes
:
public_attributes
.
remove
(
instance_attr
)
if
instance_attr
in
public_methods
:
public_methods
.
remove
(
instance_attr
)
out
.
update
(
instance_attributes
=
instance_attributes
)
public_methods
.
remove
(
instance_attr
)
out
.
update
(
instance_attributes
=
instance_attributes
)
options
.
update
(
source
=
source
)
self
.
oprint
(
out
,
**
options
)
...
...
@@ -280,16 +223,12 @@ class Console:
source
=
self
.
options
[
'source'
]
if
'source'
in
options
.
keys
():
source
=
'{0} : {1}'
.
format
(
source
,
options
.
pop
(
'source'
)
)
source
=
'{0} : {1}'
.
format
(
source
,
options
.
pop
(
'source'
))
self
.
configure
(
**
options
)
self
.
pp
=
pprint
.
PrettyPrinter
(
indent
=
self
.
options
[
'indent'
],
width
=
self
.
options
[
'width'
],
compact
=
True
,
indent
=
self
.
options
[
'indent'
],
width
=
self
.
options
[
'width'
],
compact
=
True
)
header
=
self
.
options
[
'seperator_line'
]
.
format
(
...
...
@@ -297,10 +236,7 @@ class Console:
char
=
self
.
options
[
'seperator_char'
],
width
=
self
.
options
[
'width'
],
)
footer
=
(
self
.
options
[
'seperator_char'
]
*
self
.
options
[
'width'
]
)
footer
=
self
.
options
[
'seperator_char'
]
*
self
.
options
[
'width'
]
sys
.
stdout
.
write
(
self
.
colorize
(
header
))
sys
.
stdout
.
write
(
'
\n
'
)
...
...
applications/baseapp/utils/upload_handler.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -8,9 +8,7 @@ from baseapp.utils import urlify
__all__
=
[
'save_file'
]
def
save_file
(
instance
,
filename
,
upload_to
=
'upload/
%
Y/
%
m/
%
d/'
):
def
save_file
(
instance
,
filename
,
upload_to
=
'upload/
%
Y/
%
m/
%
d/'
):
"""
By default, this saves to : `MEDIA_ROOT/upload/2017/09/06/`
...
...
@@ -35,15 +33,11 @@ def save_file(
"""
file_basename
,
file_extension
=
os
.
path
.
splitext
(
filename
)
file_basename
,
file_extension
=
os
.
path
.
splitext
(
filename
)
file_savename
=
'{safe_basename}{extension}'
.
format
(
safe_basename
=
slugify
(
urlify
(
file_basename
)),
extension
=
file_extension
.
lower
(),
safe_basename
=
slugify
(
urlify
(
file_basename
)),
extension
=
file_extension
.
lower
()
)
now
=
datetime
.
datetime
.
now
()
return
'{upload_to}{file_savename}'
.
format
(
upload_to
=
now
.
strftime
(
upload_to
),
file_savename
=
file_savename
,
upload_to
=
now
.
strftime
(
upload_to
),
file_savename
=
file_savename
)
applications/baseapp/utils/urlify.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -42,12 +42,7 @@ def urlify(value, language='tr'):
"""
return
''
.
join
(
map
(
lambda
char
:
LETTER_TRANSFORM_MAP
[
language
]
.
get
(
char
,
char
),
iter
(
value
),
)
map
(
lambda
char
:
LETTER_TRANSFORM_MAP
[
language
]
.
get
(
char
,
char
),
iter
(
value
))
)
.
lower
()
...
...
applications/baseapp/views/__init__.py
Dosyayı görüntüle @
dbcf1c9d
# isort:skip_file
# flake8: noqa
from
.index
import
*
applications/baseapp/views/index.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -16,11 +16,7 @@ class IndexView(HtmlDebugMixin, TemplateView):
self
.
hdbg
(
'This'
,
'is'
,
'an'
,
'example'
,
'of'
)
self
.
hdbg
(
'self.hdbg'
,
'usage'
)
self
.
hdbg
(
self
.
request
.
META
)
self
.
hdbg
(
slugify
(
urlify
(
'Merhaba Dünya! Ben Uğur Özyılmazel'
)
)
)
self
.
hdbg
(
slugify
(
urlify
(
'Merhaba Dünya! Ben Uğur Özyılmazel'
)))
kwargs
=
super
()
.
get_context_data
(
**
kwargs
)
query_string_p
=
numerify
(
self
.
request
.
GET
.
get
(
'p'
))
...
...
applications/baseapp/widgets/__init__.py
Dosyayı görüntüle @
dbcf1c9d
from
.image_file
import
*
# noqa
# isort:skip_file
# flake8: noqa
from
.image_file
import
*
config/settings/base.py
Dosyayı görüntüle @
dbcf1c9d
import
os
import
sys
BASE_DIR
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
)
)
BASE_DIR
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))))
SECRET_KEY
=
os
.
environ
.
get
(
'DJANGO_SECRET'
)
sys
.
path
.
append
(
os
.
path
.
join
(
BASE_DIR
,
'applications'
))
...
...
config/settings/development.example.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -16,9 +16,7 @@ DATABASES = {
'default'
:
{
'ENGINE'
:
'django.db.backends.sqlite3'
,
'NAME'
:
os
.
path
.
join
(
# noqa: F405
BASE_DIR
,
# noqa: F405
'db'
,
'development.sqlite3'
,
# noqa: F405
BASE_DIR
,
'db'
,
'development.sqlite3'
# noqa: F405 # noqa: F405
),
}
}
...
...
@@ -26,21 +24,11 @@ DATABASES = {
# uncomment for PostgreSQL
# DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql', 'NAME': 'NAME_OF_YOUR_DB'}}
STATICFILES_DIRS
=
(
os
.
path
.
join
(
BASE_DIR
,
'static'
),
# noqa: F405
)
STATICFILES_DIRS
=
(
os
.
path
.
join
(
BASE_DIR
,
'static'
),)
# noqa: F405
MEDIA_ROOT
=
os
.
path
.
join
(
BASE_DIR
,
'media'
)
# noqa: F405
WERKZUEG_FILTER_EXTENSTIONS
=
[
'css'
,
'js'
,
'png'
,
'jpg'
,
'svg'
,
'gif'
,
'woff'
,
]
WERKZUEG_FILTER_EXTENSTIONS
=
[
'css'
,
'js'
,
'png'
,
'jpg'
,
'svg'
,
'gif'
,
'woff'
]
LOGGING
=
{
'version'
:
1
,
...
...
@@ -80,10 +68,7 @@ LOGGING = {
'level'
:
'DEBUG'
,
'propagate'
:
True
,
},
'app'
:
{
'handlers'
:
[
'console_custom'
],
'level'
:
'DEBUG'
,
},
'app'
:
{
'handlers'
:
[
'console_custom'
],
'level'
:
'DEBUG'
},
# enable this block if you want to see SQL queries :)
# 'django.db.backends': {
# 'handlers': ['console_sql'],
...
...
@@ -93,9 +78,7 @@ LOGGING = {
}
# middlewares for development purposes only
MIDDLEWARE
+=
[
# noqa: F405
'debug_toolbar.middleware.DebugToolbarMiddleware'
]
MIDDLEWARE
+=
[
'debug_toolbar.middleware.DebugToolbarMiddleware'
]
# noqa: F405
# apps for development purposes only
INSTALLED_APPS
+=
[
'debug_toolbar'
]
# noqa: F405
config/settings/heroku.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -12,36 +12,21 @@ ALLOWED_HOSTS = [
]
DATABASES
=
{
'default'
:
db_from_env
}
SECURE_PROXY_SSL_HEADER
=
(
'HTTP_X_FORWARDED_PROTO'
,
'https'
,
)
SECURE_PROXY_SSL_HEADER
=
(
'HTTP_X_FORWARDED_PROTO'
,
'https'
)
AUTH_PASSWORD_VALIDATORS
=
[
{
'NAME'
:
'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'
},
{
'NAME'
:
'django.contrib.auth.password_validation.MinimumLengthValidator'
},
{
'NAME'
:
'django.contrib.auth.password_validation.CommonPasswordValidator'
},
{
'NAME'
:
'django.contrib.auth.password_validation.NumericPasswordValidator'
},
{
'NAME'
:
'django.contrib.auth.password_validation.MinimumLengthValidator'
},
{
'NAME'
:
'django.contrib.auth.password_validation.CommonPasswordValidator'
},
{
'NAME'
:
'django.contrib.auth.password_validation.NumericPasswordValidator'
},
]
STATICFILES_STORAGE
=
(
'whitenoise.django.GzipManifestStaticFilesStorage'
)
STATIC_ROOT
=
os
.
path
.
join
(
# noqa: F405
BASE_DIR
,
'staticfiles'
# noqa: F405
)
STATICFILES_STORAGE
=
'whitenoise.django.GzipManifestStaticFilesStorage'
STATIC_ROOT
=
os
.
path
.
join
(
BASE_DIR
,
'staticfiles'
)
# noqa: F405 # noqa: F405
STATICFILES_DIRS
=
(
os
.
path
.
join
(
BASE_DIR
,
'static'
),
# noqa: F405
)
STATICFILES_DIRS
=
(
os
.
path
.
join
(
BASE_DIR
,
'static'
),)
# noqa: F405
MEDIA_ROOT
=
os
.
path
.
join
(
BASE_DIR
,
'media'
)
# noqa: F405
# fmt: off
...
...
@@ -57,18 +42,14 @@ MIDDLEWARE.insert( # noqa: F405
# fmt: on
LOGGING_CONFIG
=
None
LOGLEVEL
=
os
.
environ
.
get
(
# noqa: F405
'LOGLEVEL'
,
'info'
)
.
upper
()
LOGLEVEL
=
os
.
environ
.
get
(
'LOGLEVEL'
,
'info'
)
.
upper
()
# noqa: F405
logging
.
config
.
dictConfig
(
{
'version'
:
1
,
'disable_existing_loggers'
:
False
,
'formatters'
:
{
'default'
:
{
'format'
:
'
%(asctime)
s
%(name)-12
s
%(levelname)-8
s
%(message)
s'
}
'default'
:
{
'format'
:
'
%(asctime)
s
%(name)-12
s
%(levelname)-8
s
%(message)
s'
}
},
'handlers'
:
{
'mail_admins'
:
{
...
...
@@ -90,11 +71,7 @@ logging.config.dictConfig(
},
'loggers'
:
{
''
:
{
'level'
:
'DEBUG'
,
'handlers'
:
[
'stdout'
]},
'app'
:
{
'level'
:
LOGLEVEL
,
'handlers'
:
[
'stdout'
],
'propagate'
:
False
,
},
'app'
:
{
'level'
:
LOGLEVEL
,
'handlers'
:
[
'stdout'
],
'propagate'
:
False
},
'django.request'
:
{
'handlers'
:
[
'mail_admins'
],
'level'
:
'ERROR'
,
...
...
config/settings/test.example.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -2,15 +2,8 @@ from .base import * # noqa pylint: disable=E0401
SECRET_KEY
=
'fake-key'
DATABASES
=
{
'default'
:
{
'ENGINE'
:
'django.db.backends.sqlite3'
,
'NAME'
:
':memory:'
,
}
}
DATABASES
=
{
'default'
:
{
'ENGINE'
:
'django.db.backends.sqlite3'
,
'NAME'
:
':memory:'
}}
PASSWORD_HASHERS
=
(
'django.contrib.auth.hashers.MD5PasswordHasher'
,
)
PASSWORD_HASHERS
=
(
'django.contrib.auth.hashers.MD5PasswordHasher'
,)
MIGRATION_MODULES
=
{
'baseapp'
:
None
}
config/settings/travis.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -2,15 +2,8 @@ from .base import * # noqa pylint: disable=E0401
SECRET_KEY
=
'fake-key'
DATABASES
=
{
'default'
:
{
'ENGINE'
:
'django.db.backends.sqlite3'
,
'NAME'
:
':memory:'
,
}
}
DATABASES
=
{
'default'
:
{
'ENGINE'
:
'django.db.backends.sqlite3'
,
'NAME'
:
':memory:'
}}
PASSWORD_HASHERS
=
(
'django.contrib.auth.hashers.MD5PasswordHasher'
,
)
PASSWORD_HASHERS
=
(
'django.contrib.auth.hashers.MD5PasswordHasher'
,)
MIGRATION_MODULES
=
{
'baseapp'
:
None
}
config/wsgi.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -3,10 +3,7 @@ import os
from
django.core.wsgi
import
get_wsgi_application
os
.
environ
.
setdefault
(
'DJANGO_SETTINGS_MODULE'
,
'config.settings.{0}'
.
format
(
os
.
environ
.
get
(
'DJANGO_ENV'
)
),
'DJANGO_SETTINGS_MODULE'
,
'config.settings.{0}'
.
format
(
os
.
environ
.
get
(
'DJANGO_ENV'
))
)
application
=
get_wsgi_application
()
install.sh
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -18,9 +18,10 @@ color_8=$(tput setaf 8) # gray
color_r
=
$(
tput sgr0
)
# reset
AVAILABLE_OPTIONS
=(
"Django 2.1.7"
"Django 2.1.5"
"Django 2.0.5"
"Django 2.1.3"
"Django 2.0.5"
"Cancel and quit"
)
...
...
@@ -29,18 +30,22 @@ PS3="Select option:"
select
i
in
"
${
AVAILABLE_OPTIONS
[@]
}
"
do
case
$i
in
"Django 2.1.
5
"
)
PACKAGE
=
"django-2.1.
5
"
"Django 2.1.
7
"
)
PACKAGE
=
"django-2.1.
7
"
break
;;
"Django 2.
0
.5"
)
PACKAGE
=
"django-2.
0
.5"
"Django 2.
1
.5"
)
PACKAGE
=
"django-2.
1
.5"
break
;;
"Django 2.1.3"
)
PACKAGE
=
"django-2.1.3"
break
;;
"Django 2.0.5"
)
PACKAGE
=
"django-2.0.5"
break
;;
"Cancel and quit"
)
echo
"Canceled..."
exit
1
...
...
logging_helpers/__init__.py
Dosyayı görüntüle @
dbcf1c9d
# isort:skip_file
# flake8: noqa
from
.formatters
import
*
from
.werkzueg_filters
import
*
logging_helpers/formatters.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -3,10 +3,7 @@ import re
from
django.core.management.color
import
color_style
__all__
=
[
'CustomWerkzeugLogFormatter'
,
'CustomSqlLogFormatter'
,
]
__all__
=
[
'CustomWerkzeugLogFormatter'
,
'CustomSqlLogFormatter'
]
ansi_escape
=
re
.
compile
(
r'\x1b[^m]*m'
)
...
...
@@ -45,9 +42,7 @@ class CustomWerkzeugLogFormatter(logging.Formatter):
levelname
=
record
.
levelname
.
lower
()
levelstyle
=
self
.
style
.
SUCCESS
record
.
levelname
=
'{0:.<14}'
.
format
(
record
.
levelname
)
record
.
levelname
=
'{0:.<14}'
.
format
(
record
.
levelname
)
if
levelname
==
'warning'
:
levelstyle
=
self
.
style
.
WARNING
...
...
@@ -70,8 +65,6 @@ class CustomSqlLogFormatter(logging.Formatter):
def
format
(
self
,
record
):
# noqa: A003
record
.
levelname
=
'{0:.<14}'
.
format
(
'SQL'
)
record
.
levelname
=
self
.
style
.
HTTP_INFO
(
record
.
levelname
)
record
.
levelname
=
self
.
style
.
HTTP_INFO
(
record
.
levelname
)
record
.
sql
=
self
.
style
.
SQL_KEYWORD
(
record
.
sql
)
return
super
()
.
format
(
record
)
logging_helpers/werkzueg_filters.py
Dosyayı görüntüle @
dbcf1c9d
...
...
@@ -4,15 +4,10 @@ __all__ = ['werkzueg_filter_extenstions_callback']
def
werkzueg_filter_extenstions_callback
(
record
):
extensions_to_filter
=
getattr
(
settings
,
'WERKZUEG_FILTER_EXTENSTIONS'
,
False
)
extensions_to_filter
=
getattr
(
settings
,
'WERKZUEG_FILTER_EXTENSTIONS'
,
False
)
if
extensions_to_filter
:
return
not
any
(
[
'.{0}'
.
format
(
ext
)
in
record
.
msg
for
ext
in
extensions_to_filter
]
[
'.{0}'
.
format
(
ext
)
in
record
.
msg
for
ext
in
extensions_to_filter
]
)
else
:
return
True
pyproject.toml
Dosyayı görüntüle @
dbcf1c9d
[tool.black]
line-length
=
60
line-length
=
88
py36
=
true
skip-string-normalization
=
true
quiet
=
true
...
...
requirements/base.pip
Dosyayı görüntüle @
dbcf1c9d
Django==2.1.
5
Django==2.1.
7
Pillow==5.4.1
django-extensions==2.1.4
\ No newline at end of file
django-extensions==2.1.6
python-slugify==3.0.0
requirements/development.pip
Dosyayı görüntüle @
dbcf1c9d
-r base.pip
ipython==7.
1.1
Werkzeug==0.1
4.1
ipython==7.
3.0
Werkzeug==0.1
5.0
django-debug-toolbar==1.11
coverage==4.5.
2
isort==4.3.
4
black==1
8.9
b0
flake8==3.
6.0
flake8-bandit==2.
0
.0
coverage==4.5.
3
isort==4.3.
15
black==1
9.3
b0
flake8==3.
7.7
flake8-bandit==2.
1
.0
flake8-blind-except==0.1.1
flake8-bugbear==18.8.0
flake8-builtins==1.4.1
...
...
requirements/heroku.pip
Dosyayı görüntüle @
dbcf1c9d
-r base.pip
gunicorn==19.9.0
psycopg2-binary==2.7.
6.1
psycopg2-binary==2.7.
7
dj-database-url==0.5.0
whitenoise==4.1.2
\ No newline at end of file
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