mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2025-01-24 16:24:14 +03:00
Option for DRF with extra fixes (#2410)
Option for DRF with extra fixes
This commit is contained in:
commit
2fb40f3f8c
|
@ -130,6 +130,7 @@ Listed in alphabetical order.
|
||||||
Ivan Khomutov `@ikhomutov`_
|
Ivan Khomutov `@ikhomutov`_
|
||||||
Jan Van Bruggen `@jvanbrug`_
|
Jan Van Bruggen `@jvanbrug`_
|
||||||
Jelmer Draaijer `@foarsitter`_
|
Jelmer Draaijer `@foarsitter`_
|
||||||
|
Jerome Caisip `@jeromecaisip`_
|
||||||
Jens Nilsson `@phiberjenz`_
|
Jens Nilsson `@phiberjenz`_
|
||||||
Jerome Leclanche `@jleclanche`_ @Adys
|
Jerome Leclanche `@jleclanche`_ @Adys
|
||||||
Jimmy Gitonga `@afrowave`_ @afrowave
|
Jimmy Gitonga `@afrowave`_ @afrowave
|
||||||
|
@ -299,6 +300,7 @@ Listed in alphabetical order.
|
||||||
.. _@jangeador: https://github.com/jangeador
|
.. _@jangeador: https://github.com/jangeador
|
||||||
.. _@jazztpt: https://github.com/jazztpt
|
.. _@jazztpt: https://github.com/jazztpt
|
||||||
.. _@jcass77: https://github.com/jcass77
|
.. _@jcass77: https://github.com/jcass77
|
||||||
|
.. _@jeromecaisip: https://github.com/jeromecaisip
|
||||||
.. _@jleclanche: https://github.com/jleclanche
|
.. _@jleclanche: https://github.com/jleclanche
|
||||||
.. _@juliocc: https://github.com/juliocc
|
.. _@juliocc: https://github.com/juliocc
|
||||||
.. _@jvanbrug: https://github.com/jvanbrug
|
.. _@jvanbrug: https://github.com/jvanbrug
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
"GCP",
|
"GCP",
|
||||||
"None"
|
"None"
|
||||||
],
|
],
|
||||||
|
"use_drf": "n",
|
||||||
"custom_bootstrap_compilation": "n",
|
"custom_bootstrap_compilation": "n",
|
||||||
"use_compressor": "n",
|
"use_compressor": "n",
|
||||||
"use_celery": "n",
|
"use_celery": "n",
|
||||||
|
|
|
@ -287,6 +287,11 @@ def remove_aws_dockerfile():
|
||||||
shutil.rmtree(os.path.join("compose", "production", "aws"))
|
shutil.rmtree(os.path.join("compose", "production", "aws"))
|
||||||
|
|
||||||
|
|
||||||
|
def remove_drf_starter_files():
|
||||||
|
os.remove(os.path.join("config", "api_router.py"))
|
||||||
|
shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "users", "api"))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
debug = "{{ cookiecutter.debug }}".lower() == "y"
|
debug = "{{ cookiecutter.debug }}".lower() == "y"
|
||||||
|
|
||||||
|
@ -359,6 +364,9 @@ def main():
|
||||||
if "{{ cookiecutter.ci_tool }}".lower() != "gitlab":
|
if "{{ cookiecutter.ci_tool }}".lower() != "gitlab":
|
||||||
remove_dotgitlabciyml_file()
|
remove_dotgitlabciyml_file()
|
||||||
|
|
||||||
|
if "{{ cookiecutter.use_drf }}".lower() == "n":
|
||||||
|
remove_drf_starter_files()
|
||||||
|
|
||||||
print(SUCCESS + "Project initialized, keep up the good work!" + TERMINATOR)
|
print(SUCCESS + "Project initialized, keep up the good work!" + TERMINATOR)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ def context():
|
||||||
@pytest.mark.parametrize("use_mailhog", ["y", "n"], ids=lambda yn: f"mailhog:{yn}")
|
@pytest.mark.parametrize("use_mailhog", ["y", "n"], ids=lambda yn: f"mailhog:{yn}")
|
||||||
@pytest.mark.parametrize("use_sentry", ["y", "n"], ids=lambda yn: f"sentry:{yn}")
|
@pytest.mark.parametrize("use_sentry", ["y", "n"], ids=lambda yn: f"sentry:{yn}")
|
||||||
@pytest.mark.parametrize("use_compressor", ["y", "n"], ids=lambda yn: f"cmpr:{yn}")
|
@pytest.mark.parametrize("use_compressor", ["y", "n"], ids=lambda yn: f"cmpr:{yn}")
|
||||||
|
@pytest.mark.parametrize("use_drf", ["y", "n"], ids=lambda yn: f"drf:{yn}")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"use_whitenoise,cloud_provider",
|
"use_whitenoise,cloud_provider",
|
||||||
[
|
[
|
||||||
|
@ -53,6 +54,7 @@ def context_combination(
|
||||||
use_sentry,
|
use_sentry,
|
||||||
use_compressor,
|
use_compressor,
|
||||||
use_whitenoise,
|
use_whitenoise,
|
||||||
|
use_drf,
|
||||||
cloud_provider,
|
cloud_provider,
|
||||||
):
|
):
|
||||||
"""Fixture that parametrize the function where it's used."""
|
"""Fixture that parametrize the function where it's used."""
|
||||||
|
@ -64,6 +66,7 @@ def context_combination(
|
||||||
"use_mailhog": use_mailhog,
|
"use_mailhog": use_mailhog,
|
||||||
"use_sentry": use_sentry,
|
"use_sentry": use_sentry,
|
||||||
"use_whitenoise": use_whitenoise,
|
"use_whitenoise": use_whitenoise,
|
||||||
|
"use_drf": use_drf,
|
||||||
"cloud_provider": cloud_provider,
|
"cloud_provider": cloud_provider,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
{{cookiecutter.project_slug}}/config/api_router.py
Normal file
14
{{cookiecutter.project_slug}}/config/api_router.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
from rest_framework.routers import DefaultRouter, SimpleRouter
|
||||||
|
from django.conf import settings
|
||||||
|
from {{ cookiecutter.project_slug }}.users.api.views import UserViewSet
|
||||||
|
|
||||||
|
if settings.DEBUG:
|
||||||
|
router = DefaultRouter()
|
||||||
|
else:
|
||||||
|
router = SimpleRouter()
|
||||||
|
|
||||||
|
router.register("users", UserViewSet)
|
||||||
|
|
||||||
|
|
||||||
|
app_name = "api"
|
||||||
|
urlpatterns = router.urls
|
|
@ -301,14 +301,24 @@ ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
||||||
ACCOUNT_ADAPTER = "{{cookiecutter.project_slug}}.users.adapters.AccountAdapter"
|
ACCOUNT_ADAPTER = "{{cookiecutter.project_slug}}.users.adapters.AccountAdapter"
|
||||||
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||||
SOCIALACCOUNT_ADAPTER = "{{cookiecutter.project_slug}}.users.adapters.SocialAccountAdapter"
|
SOCIALACCOUNT_ADAPTER = "{{cookiecutter.project_slug}}.users.adapters.SocialAccountAdapter"
|
||||||
|
|
||||||
{% if cookiecutter.use_compressor == 'y' -%}
|
{% if cookiecutter.use_compressor == 'y' -%}
|
||||||
# django-compressor
|
# django-compressor
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://django-compressor.readthedocs.io/en/latest/quickstart/#installation
|
# https://django-compressor.readthedocs.io/en/latest/quickstart/#installation
|
||||||
INSTALLED_APPS += ["compressor"]
|
INSTALLED_APPS += ["compressor"]
|
||||||
STATICFILES_FINDERS += ["compressor.finders.CompressorFinder"]
|
STATICFILES_FINDERS += ["compressor.finders.CompressorFinder"]
|
||||||
|
{%- endif %}
|
||||||
|
{% if cookiecutter.use_drf == "y" -%}
|
||||||
|
# django-reset-framework
|
||||||
|
# -------------------------------------------------------------------------------
|
||||||
|
# django-rest-framework - https://www.django-rest-framework.org/api-guide/settings/
|
||||||
|
REST_FRAMEWORK = {
|
||||||
|
"DEFAULT_AUTHENTICATION_CLASSES": (
|
||||||
|
"rest_framework.authentication.SessionAuthentication",
|
||||||
|
"rest_framework.authentication.TokenAuthentication",
|
||||||
|
),
|
||||||
|
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
|
||||||
|
}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
# Your stuff...
|
# Your stuff...
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -4,6 +4,9 @@ from django.conf.urls.static import static
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
from django.views import defaults as default_views
|
from django.views import defaults as default_views
|
||||||
|
{% if cookiecutter.use_drf == 'y' -%}
|
||||||
|
from rest_framework.authtoken.views import obtain_auth_token
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", TemplateView.as_view(template_name="pages/home.html"), name="home"),
|
path("", TemplateView.as_view(template_name="pages/home.html"), name="home"),
|
||||||
|
@ -17,6 +20,15 @@ urlpatterns = [
|
||||||
path("accounts/", include("allauth.urls")),
|
path("accounts/", include("allauth.urls")),
|
||||||
# Your stuff: custom urls includes go here
|
# Your stuff: custom urls includes go here
|
||||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
{% if cookiecutter.use_drf == 'y' -%}
|
||||||
|
# API URLS
|
||||||
|
urlpatterns += [
|
||||||
|
# API base url
|
||||||
|
path("api/", include("config.api_router")),
|
||||||
|
# DRF auth token
|
||||||
|
path("auth-token/", obtain_auth_token),
|
||||||
|
]
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
# This allows the error pages to be debugged during development, just visit
|
# This allows the error pages to be debugged during development, just visit
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
from rest_framework import serializers
|
||||||
|
from {{ cookiecutter.project_slug }}.users.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ["username", "email", "name", "url"]
|
||||||
|
|
||||||
|
extra_kwargs = {
|
||||||
|
"url": {"view_name": "api:user-detail", "lookup_field": "username"}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.mixins import RetrieveModelMixin, ListModelMixin, UpdateModelMixin
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.viewsets import GenericViewSet
|
||||||
|
|
||||||
|
from .serializers import UserSerializer
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
class UserViewSet(RetrieveModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
|
||||||
|
serializer_class = UserSerializer
|
||||||
|
queryset = User.objects.all()
|
||||||
|
lookup_field = "username"
|
||||||
|
|
||||||
|
def get_queryset(self, *args, **kwargs):
|
||||||
|
return self.queryset.filter(id=self.request.user.id)
|
||||||
|
|
||||||
|
@action(detail=False, methods=["GET"])
|
||||||
|
def me(self, request):
|
||||||
|
serializer = UserSerializer(request.user, context={"request": request})
|
||||||
|
return Response(status=status.HTTP_200_OK, data=serializer.data)
|
Loading…
Reference in New Issue
Block a user