mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2025-08-15 09:24:52 +03:00
Changes for the cookiecutter
This commit is contained in:
parent
b018b7b8a8
commit
e531089f3e
|
@ -112,7 +112,7 @@ AUTHENTICATION_BACKENDS = [
|
|||
"allauth.account.auth_backends.AuthenticationBackend",
|
||||
]
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#auth-user-model
|
||||
AUTH_USER_MODEL = "users.User"
|
||||
AUTH_USER_MODEL = "users.Account"
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#login-redirect-url
|
||||
LOGIN_REDIRECT_URL = "users:redirect"
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#login-url
|
||||
|
|
|
@ -91,9 +91,7 @@
|
|||
<a class="nav-link" href="{% url 'about' %}">About</a>
|
||||
</li>
|
||||
{% if request.user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% endraw %}{% if cookiecutter.username_type == "email" %}{% raw %}{% url 'users:detail' request.user.pk %}{% endraw %}{% else %}{% raw %}{% url 'users:detail' request.user.username %}{% endraw %}{% endif %}{% raw %}">{% translate "My Profile" %}</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
{# URL provided by django-allauth/account/urls.py #}
|
||||
<a class="nav-link" href="{% url 'account_logout' %}">{% translate "Sign Out" %}</a>
|
||||
|
|
|
@ -3,48 +3,5 @@ from django.contrib.auth import admin as auth_admin
|
|||
from django.contrib.auth import get_user_model
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from {{ cookiecutter.project_slug }}.users.forms import UserAdminChangeForm, UserAdminCreationForm
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@admin.register(User)
|
||||
class UserAdmin(auth_admin.UserAdmin):
|
||||
form = UserAdminChangeForm
|
||||
add_form = UserAdminCreationForm
|
||||
fieldsets = (
|
||||
{%- if cookiecutter.username_type == "email" %}
|
||||
(None, {"fields": ("email", "password")}),
|
||||
(_("Personal info"), {"fields": ("name",)}),
|
||||
{%- else %}
|
||||
(None, {"fields": ("username", "password")}),
|
||||
(_("Personal info"), {"fields": ("name", "email")}),
|
||||
{%- endif %}
|
||||
(
|
||||
_("Permissions"),
|
||||
{
|
||||
"fields": (
|
||||
"is_active",
|
||||
"is_staff",
|
||||
"is_superuser",
|
||||
"groups",
|
||||
"user_permissions",
|
||||
),
|
||||
},
|
||||
),
|
||||
(_("Important dates"), {"fields": ("last_login", "date_joined")}),
|
||||
)
|
||||
list_display = ["{{cookiecutter.username_type}}", "name", "is_superuser"]
|
||||
search_fields = ["name"]
|
||||
{%- if cookiecutter.username_type == "email" %}
|
||||
ordering = ["id"]
|
||||
add_fieldsets = (
|
||||
(
|
||||
None,
|
||||
{
|
||||
"classes": ("wide",),
|
||||
"fields": ("email", "password1", "password2"),
|
||||
},
|
||||
),
|
||||
)
|
||||
{%- endif %}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
from allauth.account.forms import SignupForm
|
||||
from allauth.socialaccount.forms import SignupForm as SocialSignupForm
|
||||
from django.contrib.auth import forms as admin_forms
|
||||
from django.contrib.auth import get_user_model
|
||||
{%- if cookiecutter.username_type == "email" %}
|
||||
from django.forms import EmailField
|
||||
{%- endif %}
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class UserAdminChangeForm(admin_forms.UserChangeForm):
|
||||
class Meta(admin_forms.UserChangeForm.Meta):
|
||||
model = User
|
||||
{%- if cookiecutter.username_type == "email" %}
|
||||
field_classes = {"email": EmailField}
|
||||
{%- endif %}
|
||||
|
||||
|
||||
class UserAdminCreationForm(admin_forms.UserCreationForm):
|
||||
"""
|
||||
Form for User Creation in the Admin Area.
|
||||
To change user signup, see UserSignupForm and UserSocialSignupForm.
|
||||
"""
|
||||
|
||||
class Meta(admin_forms.UserCreationForm.Meta):
|
||||
model = User
|
||||
{%- if cookiecutter.username_type == "email" %}
|
||||
fields = ("email",)
|
||||
field_classes = {"email": EmailField}
|
||||
error_messages = {
|
||||
"email": {"unique": _("This email has already been taken.")},
|
||||
}
|
||||
{%- else %}
|
||||
error_messages = {
|
||||
"username": {"unique": _("This username has already been taken.")},
|
||||
}
|
||||
{%- endif %}
|
||||
|
||||
|
||||
class UserSignupForm(SignupForm):
|
||||
"""
|
||||
Form that will be rendered on a user sign up section/screen.
|
||||
Default fields will be added automatically.
|
||||
Check UserSocialSignupForm for accounts created from social.
|
||||
"""
|
||||
|
||||
|
||||
class UserSocialSignupForm(SocialSignupForm):
|
||||
"""
|
||||
Renders the form when user has signed up using social accounts.
|
||||
Default fields will be added automatically.
|
||||
See UserSignupForm otherwise.
|
||||
"""
|
|
@ -1,34 +1,21 @@
|
|||
from django.contrib.auth.hashers import make_password
|
||||
from django.contrib.auth.models import UserManager as DjangoUserManager
|
||||
|
||||
from django.contrib.auth.models import AbstractBaseUser
|
||||
from django.contrib.auth.models import BaseUserManager
|
||||
|
||||
class UserManager(DjangoUserManager):
|
||||
"""Custom manager for the User model."""
|
||||
|
||||
def _create_user(self, email: str, password: str | None, **extra_fields):
|
||||
"""
|
||||
Create and save a user with the given email and password.
|
||||
"""
|
||||
class UserManager(BaseUserManager):
|
||||
def create_user(self, email, password=None, **kwargs):
|
||||
if not email:
|
||||
raise ValueError("The given email must be set")
|
||||
email = self.normalize_email(email)
|
||||
user = self.model(email=email, **extra_fields)
|
||||
user.password = make_password(password)
|
||||
raise ValueError('Users must have an email address')
|
||||
|
||||
user = self.model(email=self.normalize_email(email), **kwargs)
|
||||
user.set_password(password)
|
||||
user.save(using=self._db)
|
||||
return user
|
||||
|
||||
def create_user(self, email: str, password: str | None = None, **extra_fields):
|
||||
extra_fields.setdefault("is_staff", False)
|
||||
extra_fields.setdefault("is_superuser", False)
|
||||
return self._create_user(email, password, **extra_fields)
|
||||
|
||||
def create_superuser(self, email: str, password: str | None = None, **extra_fields):
|
||||
extra_fields.setdefault("is_staff", True)
|
||||
extra_fields.setdefault("is_superuser", True)
|
||||
|
||||
if extra_fields.get("is_staff") is not True:
|
||||
raise ValueError("Superuser must have is_staff=True.")
|
||||
if extra_fields.get("is_superuser") is not True:
|
||||
raise ValueError("Superuser must have is_superuser=True.")
|
||||
|
||||
return self._create_user(email, password, **extra_fields)
|
||||
def create_superuser(self, email, password, **kwargs):
|
||||
kwargs.setdefault('is_staff', True)
|
||||
kwargs.setdefault('is_superuser', True)
|
||||
return self.create_user(email, password, **kwargs)
|
|
@ -1,139 +0,0 @@
|
|||
import django.contrib.auth.models
|
||||
import django.contrib.auth.validators
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
import {{cookiecutter.project_slug}}.users.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
("auth", "0012_alter_user_first_name_max_length"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="User",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("password", models.CharField(max_length=128, verbose_name="password")),
|
||||
(
|
||||
"last_login",
|
||||
models.DateTimeField(
|
||||
blank=True, null=True, verbose_name="last login"
|
||||
),
|
||||
),
|
||||
(
|
||||
"is_superuser",
|
||||
models.BooleanField(
|
||||
default=False,
|
||||
help_text="Designates that this user has all permissions without explicitly assigning them.",
|
||||
verbose_name="superuser status",
|
||||
),
|
||||
),
|
||||
{%- if cookiecutter.username_type == "username" -%}
|
||||
(
|
||||
"username",
|
||||
models.CharField(
|
||||
error_messages={
|
||||
"unique": "A user with that username already exists."
|
||||
},
|
||||
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
|
||||
max_length=150,
|
||||
unique=True,
|
||||
validators=[
|
||||
django.contrib.auth.validators.UnicodeUsernameValidator()
|
||||
],
|
||||
verbose_name="username",
|
||||
),
|
||||
),
|
||||
(
|
||||
"email",
|
||||
models.EmailField(
|
||||
blank=True, max_length=254, verbose_name="email address"
|
||||
),
|
||||
),
|
||||
{%- else %}
|
||||
(
|
||||
"email",
|
||||
models.EmailField(
|
||||
unique=True, max_length=254, verbose_name="email address"
|
||||
),
|
||||
),
|
||||
{%- endif %}
|
||||
(
|
||||
"is_staff",
|
||||
models.BooleanField(
|
||||
default=False,
|
||||
help_text="Designates whether the user can log into this admin site.",
|
||||
verbose_name="staff status",
|
||||
),
|
||||
),
|
||||
(
|
||||
"is_active",
|
||||
models.BooleanField(
|
||||
default=True,
|
||||
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
|
||||
verbose_name="active",
|
||||
),
|
||||
),
|
||||
(
|
||||
"date_joined",
|
||||
models.DateTimeField(
|
||||
default=django.utils.timezone.now, verbose_name="date joined"
|
||||
),
|
||||
),
|
||||
(
|
||||
"name",
|
||||
models.CharField(
|
||||
blank=True, max_length=255, verbose_name="Name of User"
|
||||
),
|
||||
),
|
||||
(
|
||||
"groups",
|
||||
models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
|
||||
related_name="user_set",
|
||||
related_query_name="user",
|
||||
to="auth.Group",
|
||||
verbose_name="groups",
|
||||
),
|
||||
),
|
||||
(
|
||||
"user_permissions",
|
||||
models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="Specific permissions for this user.",
|
||||
related_name="user_set",
|
||||
related_query_name="user",
|
||||
to="auth.Permission",
|
||||
verbose_name="user permissions",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "user",
|
||||
"verbose_name_plural": "users",
|
||||
"abstract": False,
|
||||
},
|
||||
managers=[
|
||||
{%- if cookiecutter.username_type == "email" %}
|
||||
("objects", {{cookiecutter.project_slug}}.users.models.UserManager()),
|
||||
{%- else %}
|
||||
("objects", django.contrib.auth.models.UserManager()),
|
||||
{%- endif %}
|
||||
],
|
||||
),
|
||||
]
|
|
@ -8,7 +8,7 @@ from {{ cookiecutter.project_slug }}.users.managers import UserManager
|
|||
{%- endif %}
|
||||
|
||||
|
||||
class User(AbstractUser):
|
||||
class Account(AbstractUser):
|
||||
"""
|
||||
Default custom user model for {{cookiecutter.project_name}}.
|
||||
If adding fields that need to be filled at user signup,
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
from django.urls import path
|
||||
|
||||
from {{ cookiecutter.project_slug }}.users.views import (
|
||||
user_detail_view,
|
||||
user_redirect_view,
|
||||
user_update_view,
|
||||
)
|
||||
|
||||
app_name = "users"
|
||||
urlpatterns = [
|
||||
path("~redirect/", view=user_redirect_view, name="redirect"),
|
||||
path("~update/", view=user_update_view, name="update"),
|
||||
{%- if cookiecutter.username_type == "email" %}
|
||||
path("<int:pk>/", view=user_detail_view, name="detail"),
|
||||
{%- else %}
|
||||
path("<str:username>/", view=user_detail_view, name="detail"),
|
||||
{%- endif %}
|
||||
|
||||
]
|
||||
|
|
|
@ -8,34 +8,6 @@ from django.views.generic import DetailView, RedirectView, UpdateView
|
|||
User = get_user_model()
|
||||
|
||||
|
||||
class UserDetailView(LoginRequiredMixin, DetailView):
|
||||
model = User
|
||||
{%- if cookiecutter.username_type == "email" %}
|
||||
slug_field = "id"
|
||||
slug_url_kwarg = "id"
|
||||
{%- else %}
|
||||
slug_field = "username"
|
||||
slug_url_kwarg = "username"
|
||||
{%- endif %}
|
||||
|
||||
|
||||
user_detail_view = UserDetailView.as_view()
|
||||
|
||||
|
||||
class UserUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
|
||||
model = User
|
||||
fields = ["name"]
|
||||
success_message = _("Information successfully updated")
|
||||
|
||||
def get_success_url(self):
|
||||
assert self.request.user.is_authenticated # for mypy to know that the user is authenticated
|
||||
return self.request.user.get_absolute_url()
|
||||
|
||||
def get_object(self):
|
||||
return self.request.user
|
||||
|
||||
|
||||
user_update_view = UserUpdateView.as_view()
|
||||
|
||||
|
||||
class UserRedirectView(LoginRequiredMixin, RedirectView):
|
||||
|
@ -45,7 +17,7 @@ class UserRedirectView(LoginRequiredMixin, RedirectView):
|
|||
{%- if cookiecutter.username_type == "email" %}
|
||||
return reverse("users:detail", kwargs={"pk": self.request.user.pk})
|
||||
{%- else %}
|
||||
return reverse("users:detail", kwargs={"username": self.request.user.username})
|
||||
return reverse("users:detail", kwargs={"email": self.request.user.email})
|
||||
{%- endif %}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user