Django新手求助:创建含指定字段的新用户表单及访问权限控制
Hey there! As someone new to Django, building this required registration form with access restrictions is totally doable—let's break it down step by step so you can get it up and running quickly.
First, we need to store all those custom fields somewhere. We'll create a UserProfile model linked to Django's built-in User model (which handles core auth stuff like usernames and passwords).
In your app's models.py:
from django.db import models from django.contrib.auth.models import User class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') first_name = models.CharField(max_length=100, blank=False, null=False, verbose_name="First Name") last_name = models.CharField(max_length=100, blank=False, null=False, verbose_name="Last Name") email_id = models.EmailField(blank=False, null=False, verbose_name="Email ID") # Use CharField for mobile numbers to support country codes/leading zeros mobile_no = models.CharField(max_length=15, blank=False, null=False, verbose_name="Mobile No") broker = models.CharField(max_length=100, blank=False, null=False, verbose_name="Broker") address_field1 = models.CharField(max_length=255, blank=False, null=False, verbose_name="Address Field 1") address_field2 = models.CharField(max_length=255, blank=False, null=False, verbose_name="Address Field 2") address_field3 = models.CharField(max_length=255, blank=False, null=False, verbose_name="Address Field 3") city = models.CharField(max_length=100, blank=False, null=False, verbose_name="City") state = models.CharField(max_length=100, blank=False, null=False, verbose_name="State") pin = models.CharField(max_length=10, blank=False, null=False, verbose_name="PIN Code") adhaar_card = models.CharField(max_length=12, blank=False, null=False, verbose_name="Adhaar Card No") pan_no = models.CharField(max_length=10, blank=False, null=False, verbose_name="PAN No") bank_account_no = models.CharField(max_length=20, blank=False, null=False, verbose_name="Bank Account No") bank_name = models.CharField(max_length=100, blank=False, null=False, verbose_name="Bank Name") branch = models.CharField(max_length=100, blank=False, null=False, verbose_name="Branch") def __str__(self): return f"{self.user.username}'s Profile"
Run these commands to save the model to your database:
python manage.py makemigrations python manage.py migrate
We'll use a ModelForm to auto-generate form fields from our UserProfile model, plus add password fields for creating a Django user account.
In your app's forms.py (create this file if it doesn't exist):
from django import forms from django.contrib.auth.models import User from .models import UserProfile class UserRegistrationForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput, label="Password") confirm_password = forms.CharField(widget=forms.PasswordInput, label="Confirm Password") class Meta: model = UserProfile fields = [ 'first_name', 'last_name', 'email_id', 'mobile_no', 'broker', 'address_field1', 'address_field2', 'address_field3', 'city', 'state', 'pin', 'adhaar_card', 'pan_no', 'bank_account_no', 'bank_name', 'branch' ] # Add password match validation def clean(self): cleaned_data = super().clean() password = cleaned_data.get("password") confirm_password = cleaned_data.get("confirm_password") if password != confirm_password: raise forms.ValidationError("Passwords don't match!") return cleaned_data # Save both User and UserProfile together def save(self, commit=True): user = User.objects.create_user( username=self.cleaned_data['email_id'], # Use email as username for simplicity email=self.cleaned_data['email_id'], password=self.cleaned_data['password'], first_name=self.cleaned_data['first_name'], last_name=self.cleaned_data['last_name'] ) profile = super().save(commit=False) profile.user = user if commit: profile.save() return profile
We need two main views: one to handle form submission, and a protected home page that only users who've filled the form can access.
In your app's views.py:
from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.contrib.auth import login from .forms import UserRegistrationForm def registration_view(request): # If user is already logged in and has a profile, send them home if request.user.is_authenticated and hasattr(request.user, 'profile'): return redirect('home') if request.method == 'POST': form = UserRegistrationForm(request.POST) if form.is_valid(): profile = form.save() # Auto-login the user right after registration login(request, profile.user) return redirect('home') else: form = UserRegistrationForm() return render(request, 'registration_form.html', {'form': form}) @login_required def home_view(request): # Redirect users who haven't filled the form yet if not hasattr(request.user, 'profile'): return redirect('register') return render(request, 'home.html')
Link your views to URLs in your project's urls.py:
from django.contrib import admin from django.urls import path from your_app_name.views import registration_view, home_view from django.contrib.auth.views import LoginView, LogoutView urlpatterns = [ path('admin/', admin.site.urls), path('register/', registration_view, name='register'), path('login/', LoginView.as_view(template_name='login.html'), name='login'), path('logout/', LogoutView.as_view(), name='logout'), path('', home_view, name='home'), ]
Create these templates in your app's templates folder:
registration_form.html
<!DOCTYPE html> <html> <head> <title>Complete Registration</title> </head> <body> <h2>Fill Out Your Details to Access the Site</h2> <form method="post"> {% csrf_token %} <!-- Render fields with labels for clarity --> {% for field in form %} <div> {{ field.label_tag }} {{ field }} {% if field.errors %} <span style="color: red;">{{ field.errors.0 }}</span> {% endif %} </div> {% endfor %} <button type="submit">Submit & Access Site</button> </form> </body> </html>
home.html (Protected Page)
<!DOCTYPE html> <html> <head> <title>Welcome</title> </head> <body> <h1>Welcome to the Site!</h1> <p>You've successfully completed the registration form.</p> <a href="{% url 'logout' %}">Logout</a> </body> </html>
login.html (For Returning Users)
<!DOCTYPE html> <html> <head> <title>Login</title> </head> <body> <h2>Login to Access the Site</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Login</button> </form> <p>New here? <a href="{% url 'register' %}">Complete Registration</a></p> </body> </html>
To make sure users can't bypass the form by typing in URLs directly, add a middleware that checks every request:
Create middleware.py in your app:
from django.shortcuts import redirect from django.urls import reverse class ProfileCompletionMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # Skip admin, login, and register pages exempt_paths = [reverse('login'), reverse('register'), '/admin/'] if request.path in exempt_paths: return self.get_response(request) # Redirect logged-in users without a profile to the form if request.user.is_authenticated and not hasattr(request.user, 'profile'): return redirect('register') response = self.get_response(request) return response
Add this middleware to your project's settings.py:
MIDDLEWARE = [ # ... existing middlewares 'your_app_name.middleware.ProfileCompletionMiddleware', ]
- Add Custom Validation: For fields like PAN or Adhaar, add
clean_<field_name>methods to the form to enforce format rules (e.g., PAN must be 5 letters + 4 digits + 1 letter). - Style the Form: Replace the basic field rendering with CSS to make the form look professional—bootstrap is a great option for beginners.
- Test the Flow: Register a user, check if their profile exists in the admin, try accessing the home page without filling the form, and logout/login to ensure redirection works.
内容的提问来源于stack exchange,提问作者lalit bhadouria

