Beracles commited on
Commit
7a5d455
·
1 Parent(s): fa0e770

register and models

Browse files
requirements.txt CHANGED
@@ -1,2 +1,4 @@
1
  django
2
  requests
 
 
 
1
  django
2
  requests
3
+ django-crispy-forms
4
+ crispy-bootstrap5
src/main/db.sqlite3 CHANGED
Binary files a/src/main/db.sqlite3 and b/src/main/db.sqlite3 differ
 
src/main/main/settings.py CHANGED
@@ -37,7 +37,8 @@ INSTALLED_APPS = [
37
  'django.contrib.sessions',
38
  'django.contrib.messages',
39
  'django.contrib.staticfiles',
40
-
 
41
  'helloworld',
42
  'user',
43
  ]
@@ -134,3 +135,7 @@ STATICFILES_DIRS = [
134
  # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
135
 
136
  DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
 
 
 
 
 
37
  'django.contrib.sessions',
38
  'django.contrib.messages',
39
  'django.contrib.staticfiles',
40
+ "crispy_forms",
41
+ "crispy_bootstrap5",
42
  'helloworld',
43
  'user',
44
  ]
 
135
  # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
136
 
137
  DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
138
+
139
+ CRISPY_TEMPLATE_PACK = 'bootstrap5'
140
+
141
+ AUTH_USER_MODEL = 'user.CustomUser'
src/main/templates/register.html ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {% block title %} Create an Account {% endblock %}
2
+ {% block content %}
3
+ <form method="post" class="form-group">
4
+ {% csrf_token %}
5
+ {{ form }}
6
+ <button type="submit" class="btn btn-success">Register</button>
7
+ </form>
8
+ {% endblock %}
src/main/user/admin.py CHANGED
@@ -1,3 +1,11 @@
 
 
1
  from django.contrib import admin
2
 
3
  # Register your models here.
 
 
 
 
 
 
 
1
+ from user.models import CustomUser
2
+ from django.contrib.auth.models import Group
3
  from django.contrib import admin
4
 
5
  # Register your models here.
6
+
7
+
8
+
9
+
10
+ admin.site.register(CustomUser)
11
+ admin.site.unregister(Group)
src/main/user/forms.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from django import forms
2
+ from django.contrib.auth import authenticate, password_validation
3
+ from django.contrib.auth.forms import UsernameField, ReadOnlyPasswordHashField, UserModel
4
+ from django.core.exceptions import ValidationError
5
+ from django.utils.text import capfirst
6
+ from django.utils.translation import gettext_lazy as _
7
+ from .models import CustomUser
8
+
9
+
10
+ class BaseCustomUserCreationForm(forms.ModelForm):
11
+ """
12
+ A form that creates a user, with no privileges, from the given username and
13
+ password.
14
+ """
15
+
16
+ error_messages = {
17
+ "password_mismatch": _("The two password fields didn’t match."),
18
+ }
19
+ password1 = forms.CharField(
20
+ label=_("Password"),
21
+ strip=False,
22
+ widget=forms.PasswordInput(attrs={"autocomplete": "new-password"}),
23
+ help_text=password_validation.password_validators_help_text_html(),
24
+ )
25
+ password2 = forms.CharField(
26
+ label=_("Password confirmation"),
27
+ widget=forms.PasswordInput(attrs={"autocomplete": "new-password"}),
28
+ strip=False,
29
+ help_text=_("Enter the same password as before, for verification."),
30
+ )
31
+
32
+ class Meta:
33
+ model = CustomUser
34
+ fields = ("email", "username")
35
+ field_classes = {"email": forms.EmailField}
36
+
37
+ def __init__(self, *args, **kwargs):
38
+ super().__init__(*args, **kwargs)
39
+ if self._meta.model.EMAIL_FIELD in self.fields:
40
+ self.fields[self._meta.model.EMAIL_FIELD].widget.attrs[
41
+ "autofocus"
42
+ ] = True
43
+
44
+ def clean_password2(self):
45
+ password1 = self.cleaned_data.get("password1")
46
+ password2 = self.cleaned_data.get("password2")
47
+ if password1 and password2 and password1 != password2:
48
+ raise ValidationError(
49
+ self.error_messages["password_mismatch"],
50
+ code="password_mismatch",
51
+ )
52
+ return password2
53
+
54
+ def _post_clean(self):
55
+ super()._post_clean()
56
+ # Validate the password after self.instance is updated with form data
57
+ # by super().
58
+ password = self.cleaned_data.get("password2")
59
+ if password:
60
+ try:
61
+ password_validation.validate_password(password, self.instance)
62
+ except ValidationError as error:
63
+ self.add_error("password2", error)
64
+
65
+ def save(self, commit=True):
66
+ user = super().save(commit=False)
67
+ user.set_password(self.cleaned_data["password1"])
68
+ if commit:
69
+ user.save()
70
+ if hasattr(self, "save_m2m"):
71
+ self.save_m2m()
72
+ return user
73
+
74
+
75
+ class CustomUserCreationForm(BaseCustomUserCreationForm):
76
+ def clean_username(self):
77
+ """Reject emails that differ only in case."""
78
+ email = self.cleaned_data.get("email")
79
+ if (
80
+ email
81
+ and self._meta.model.objects.filter(username__iexact=email).exists()
82
+ ):
83
+ self._update_errors(
84
+ ValidationError(
85
+ {
86
+ "email": self.instance.unique_error_message(
87
+ self._meta.model, ["email"]
88
+ )
89
+ }
90
+ )
91
+ )
92
+ else:
93
+ return email
94
+
95
+
96
+ class CustomUserChangeForm(forms.ModelForm):
97
+ password = ReadOnlyPasswordHashField(
98
+ label=_("Password"),
99
+ help_text=_(
100
+ "Raw passwords are not stored, so there is no way to see this "
101
+ "user’s password, but you can change the password using "
102
+ '<a href="{}">this form</a>.'
103
+ ),
104
+ )
105
+
106
+ class Meta:
107
+ model = CustomUser
108
+ fields = "__all__"
109
+ field_classes = {"email": UsernameField}
110
+
111
+ def __init__(self, *args, **kwargs):
112
+ super().__init__(*args, **kwargs)
113
+ password = self.fields.get("password")
114
+ if password:
115
+ password.help_text = password.help_text.format(
116
+ f"../../{self.instance.pk}/password/"
117
+ )
118
+ user_permissions = self.fields.get("user_permissions")
119
+ if user_permissions:
120
+ user_permissions.queryset = user_permissions.queryset.select_related(
121
+ "content_type"
122
+ )
123
+
124
+
125
+ class CustomAuthenticationForm(forms.Form):
126
+ """
127
+ Base class for authenticating users. Extend this to get a form that accepts
128
+ username/password logins.
129
+ """
130
+
131
+ username = UsernameField(widget=forms.TextInput(attrs={"autofocus": True}))
132
+ password = forms.CharField(
133
+ label=_("Password"),
134
+ strip=False,
135
+ widget=forms.PasswordInput(attrs={"autocomplete": "current-password"}),
136
+ )
137
+
138
+ error_messages = {
139
+ "invalid_login": _(
140
+ "Please enter a correct %(username)s and password. Note that both "
141
+ "fields may be case-sensitive."
142
+ ),
143
+ "inactive": _("This account is inactive."),
144
+ }
145
+
146
+ def __init__(self, request=None, *args, **kwargs):
147
+ """
148
+ The 'request' parameter is set for custom auth use by subclasses.
149
+ The form data comes in via the standard 'data' kwarg.
150
+ """
151
+ self.request = request
152
+ self.user_cache = None
153
+ super().__init__(*args, **kwargs)
154
+
155
+ # Set the max length and label for the "username" field.
156
+ self.email_field = UserModel._meta.get_field(UserModel.EMAIL_FIELD)
157
+ email_max_length = self.email_field.max_length or 254
158
+ self.fields["email"].max_length = email_max_length
159
+ self.fields["email"].widget.attrs["maxlength"] = email_max_length
160
+ if self.fields["email"].label is None:
161
+ self.fields["email"].label = capfirst(
162
+ self.email_field.verbose_name)
163
+
164
+ def clean(self):
165
+ email = self.cleaned_data.get("username")
166
+ password = self.cleaned_data.get("password")
167
+
168
+ if email is not None and password:
169
+ self.user_cache = authenticate(
170
+ self.request, email=email, password=password
171
+ )
172
+ if self.user_cache is None:
173
+ raise self.get_invalid_login_error()
174
+ else:
175
+ self.confirm_login_allowed(self.user_cache)
176
+
177
+ return self.cleaned_data
178
+
179
+ def confirm_login_allowed(self, user):
180
+ """
181
+ Controls whether the given User may log in. This is a policy setting,
182
+ independent of end-user authentication. This default behavior is to
183
+ allow login by active users, and reject login by inactive users.
184
+
185
+ If the given user cannot log in, this method should raise a
186
+ ``ValidationError``.
187
+
188
+ If the given user may log in, this method should return None.
189
+ """
190
+ if not user.is_active:
191
+ raise ValidationError(
192
+ self.error_messages["inactive"],
193
+ code="inactive",
194
+ )
195
+
196
+ def get_user(self):
197
+ return self.user_cache
198
+
199
+ def get_invalid_login_error(self):
200
+ return ValidationError(
201
+ self.error_messages["invalid_login"],
202
+ code="invalid_login",
203
+ params={"email": self.email_field.verbose_name},
204
+ )
205
+
206
+
207
+ class RegisterForm(CustomUserCreationForm):
208
+ email = forms.EmailField()
209
+
210
+ class Meta:
211
+ model = CustomUser
212
+ fields = ['email', 'username', 'password1', 'password2']
src/main/user/migrations/0001_initial.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated by Django 5.0.3 on 2024-03-25 13:35
2
+
3
+ import django.core.validators
4
+ import django.utils.timezone
5
+ import user.models
6
+ from django.db import migrations, models
7
+
8
+
9
+ class Migration(migrations.Migration):
10
+
11
+ initial = True
12
+
13
+ dependencies = [
14
+ ('auth', '0012_alter_user_first_name_max_length'),
15
+ ]
16
+
17
+ operations = [
18
+ migrations.CreateModel(
19
+ name='CustomUser',
20
+ fields=[
21
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22
+ ('password', models.CharField(max_length=128, verbose_name='password')),
23
+ ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
24
+ ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
25
+ ('email', models.EmailField(error_messages={'unique': 'A user with that email already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.core.validators.EmailValidator()], verbose_name='email')),
26
+ ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
27
+ ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
28
+ ('username', models.CharField(blank=True, max_length=150, verbose_name='username')),
29
+ ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
30
+ ('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')),
31
+ ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
32
+ ('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')),
33
+ ('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')),
34
+ ],
35
+ options={
36
+ 'verbose_name': 'user',
37
+ 'verbose_name_plural': 'users',
38
+ 'abstract': False,
39
+ 'swappable': 'AUTH_USER_MODEL',
40
+ },
41
+ managers=[
42
+ ('objects', user.models.CustomUserManager()),
43
+ ],
44
+ ),
45
+ ]
src/main/user/models.py CHANGED
@@ -1,3 +1,162 @@
1
  from django.db import models
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  # Create your models here.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from django.db import models
2
+ from django.contrib.auth.models import (
3
+ AbstractBaseUser, PermissionsMixin, BaseUserManager)
4
+ from django.core.validators import EmailValidator
5
+ from django.core.mail import send_mail
6
+ from django.utils import timezone
7
+ from django.utils.translation import gettext_lazy as _
8
+ from django.apps import apps
9
+ from django.contrib.auth.hashers import make_password
10
+ from django.contrib import auth
11
+
12
+
13
+ class CustomUserManager(BaseUserManager):
14
+ use_in_migrations = True
15
+
16
+ def _create_user(self, username, email, password, **extra_fields):
17
+ """
18
+ Create and save a user with the given username, email, and password.
19
+ """
20
+ if not email:
21
+ raise ValueError("The given email must be set")
22
+ email = self.normalize_email(email)
23
+ # Lookup the real model class from the global app registry so this
24
+ # manager method can be used in migrations. This is fine because
25
+ # managers are by definition working on the real model.
26
+ GlobalUserModel = apps.get_model(
27
+ self.model._meta.app_label, self.model._meta.object_name
28
+ )
29
+ username = GlobalUserModel.normalize_username(username)
30
+ user = self.model(username=username, email=email, **extra_fields)
31
+ user.password = make_password(password)
32
+ user.save(using=self._db)
33
+ return user
34
+
35
+ def create_user(self, email, username=None, password=None, **extra_fields):
36
+ extra_fields.setdefault("is_staff", False)
37
+ extra_fields.setdefault("is_superuser", False)
38
+ return self._create_user(username, email, password, **extra_fields)
39
+
40
+ def create_superuser(self, username, email=None, password=None, **extra_fields):
41
+ extra_fields.setdefault("is_staff", True)
42
+ extra_fields.setdefault("is_superuser", True)
43
+
44
+ if extra_fields.get("is_staff") is not True:
45
+ raise ValueError("Superuser must have is_staff=True.")
46
+ if extra_fields.get("is_superuser") is not True:
47
+ raise ValueError("Superuser must have is_superuser=True.")
48
+
49
+ return self._create_user(username, email, password, **extra_fields)
50
+
51
+ def with_perm(
52
+ self, perm, is_active=True, include_superusers=True, backend=None, obj=None
53
+ ):
54
+ if backend is None:
55
+ backends = auth._get_backends(return_tuples=True)
56
+ if len(backends) == 1:
57
+ backend, _ = backends[0]
58
+ else:
59
+ raise ValueError(
60
+ "You have multiple authentication backends configured and "
61
+ "therefore must provide the `backend` argument."
62
+ )
63
+ elif not isinstance(backend, str):
64
+ raise TypeError(
65
+ "backend must be a dotted import path string (got %r)." % backend
66
+ )
67
+ else:
68
+ backend = auth.load_backend(backend)
69
+ if hasattr(backend, "with_perm"):
70
+ return backend.with_perm(
71
+ perm,
72
+ is_active=is_active,
73
+ include_superusers=include_superusers,
74
+ obj=obj,
75
+ )
76
+ return self.none()
77
 
78
  # Create your models here.
79
+
80
+
81
+ class AbstractCustomUser(AbstractBaseUser, PermissionsMixin):
82
+ """
83
+ An abstract base class implementing a fully featured User model with
84
+ admin-compliant permissions.
85
+
86
+ Email and password are required. Other fields are optional.
87
+ """
88
+
89
+ email_validator = EmailValidator()
90
+
91
+ email = models.EmailField(
92
+ _("email"),
93
+ max_length=150,
94
+ unique=True,
95
+ help_text=_(
96
+ "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
97
+ ),
98
+ validators=[email_validator],
99
+ error_messages={
100
+ "unique": _("A user with that email already exists."),
101
+ },
102
+ )
103
+ first_name = models.CharField(_("first name"), max_length=150, blank=True)
104
+ last_name = models.CharField(_("last name"), max_length=150, blank=True)
105
+ username = models.CharField(_("username"), max_length=150, blank=True)
106
+ is_staff = models.BooleanField(
107
+ _("staff status"),
108
+ default=False,
109
+ help_text=_(
110
+ "Designates whether the user can log into this admin site."),
111
+ )
112
+ is_active = models.BooleanField(
113
+ _("active"),
114
+ default=True,
115
+ help_text=_(
116
+ "Designates whether this user should be treated as active. "
117
+ "Unselect this instead of deleting accounts."
118
+ ),
119
+ )
120
+ date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
121
+
122
+ objects = CustomUserManager()
123
+
124
+ EMAIL_FIELD = "username"
125
+ USERNAME_FIELD = "email"
126
+ REQUIRED_FIELDS = ["username"]
127
+
128
+ class Meta:
129
+ verbose_name = _("user")
130
+ verbose_name_plural = _("users")
131
+ abstract = True
132
+
133
+ def clean(self):
134
+ super().clean()
135
+ self.email = self.__class__.objects.normalize_email(self.email)
136
+
137
+ def get_full_name(self):
138
+ """
139
+ Return the first_name plus the last_name, with a space in between.
140
+ """
141
+ full_name = "%s %s" % (self.first_name, self.last_name)
142
+ return full_name.strip()
143
+
144
+ def get_short_name(self):
145
+ """Return the short name for the user."""
146
+ return self.first_name
147
+
148
+ def email_user(self, subject, message, from_email=None, **kwargs):
149
+ """Send an email to this user."""
150
+ send_mail(subject, message, from_email, [self.email], **kwargs)
151
+
152
+
153
+ class CustomUser(AbstractCustomUser):
154
+ """
155
+ Users within the Django authentication system are represented by this
156
+ model.
157
+
158
+ Email and password are required. Other fields are optional.
159
+ """
160
+
161
+ class Meta(AbstractCustomUser.Meta):
162
+ swappable = "AUTH_USER_MODEL"
src/main/user/urls.py CHANGED
@@ -21,4 +21,5 @@ app_name = 'user'
21
  urlpatterns = [
22
  path('login/', views.login, name="login"),
23
  path('verify_password/', views.verify_password),
 
24
  ]
 
21
  urlpatterns = [
22
  path('login/', views.login, name="login"),
23
  path('verify_password/', views.verify_password),
24
+ path('register/', views.register, name="register"),
25
  ]
src/main/user/utils.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .models import CustomUser
2
+
3
+
4
+ def export_user_to_json():
5
+ # q=CustomUser.objects.create(key="value") # 插入数据
6
+ q = list(q)
7
+ for i in q:
8
+ print(i.email)
9
+ print(i.password)
10
+ print(i.username)
11
+ # todo: 写入json文件
src/main/user/views.py CHANGED
@@ -1,9 +1,9 @@
1
  import os
2
  from django.http import HttpResponse, HttpResponseRedirect
3
  from django.shortcuts import render, redirect
 
4
  import requests
5
  from . import status
6
-
7
  # Create your views here.
8
 
9
  base_url = "https://pgsoft-pguser.hf.space"
@@ -68,3 +68,16 @@ def verify_password(request) -> HttpResponse | HttpResponseRedirect:
68
  "email": email,
69
  }
70
  return render(request, "loggedin.html", context)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
  from django.http import HttpResponse, HttpResponseRedirect
3
  from django.shortcuts import render, redirect
4
+ from .forms import RegisterForm
5
  import requests
6
  from . import status
 
7
  # Create your views here.
8
 
9
  base_url = "https://pgsoft-pguser.hf.space"
 
68
  "email": email,
69
  }
70
  return render(request, "loggedin.html", context)
71
+
72
+
73
+ def register(request):
74
+ if request.method == "POST":
75
+ print("posting")
76
+ form = RegisterForm(request.POST)
77
+ if form.is_valid():
78
+ form.save()
79
+ # upload to dataset
80
+ return redirect("/")
81
+ else:
82
+ form = RegisterForm()
83
+ return render(request, "register.html", {"form": form})