You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django 2中实现类似Instagram的多账号登录注册功能?

Hey there! Let's walk through the best way to build Instagram-style login and registration in Django 2. I’ve built similar flows before, so this approach is clean, maintainable, and aligns exactly with your requirements.

1. Start with a Custom User Model

Django’s default User model is missing two critical pieces for your use case: a phone number field and enforced uniqueness for emails. We’ll extend AbstractUser to fix this—this keeps all the built-in auth functionality while adding our custom fields.

# accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.core.validators import RegexValidator

class CustomUser(AbstractUser):
    # Add phone number with regex validation to ensure valid formatting
    phone_regex = RegexValidator(
        regex=r'^\+?1?\d{9,15}$',
        message="Phone number must be entered like '+999999999' (up to 15 digits)."
    )
    phone_number = models.CharField(
        validators=[phone_regex],
        max_length=17,
        blank=True,
        unique=True,
        help_text="Optional. Enter a valid phone number."
    )
    # Make email unique (Django's default allows duplicate emails)
    email = models.EmailField(unique=True, blank=False)

    # Required settings for custom user models
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']  # Ensure email is mandatory for registration

    def __str__(self):
        return self.username

Don’t forget to tell Django to use this custom model in your settings.py:

# settings.py
AUTH_USER_MODEL = 'accounts.CustomUser'
2. Build the Registration Form

Next, we need a form that lets users sign up with either (username + email + password) or (username + phone + password) (or both, if you want). We’ll extend Django’s UserCreationForm to add the phone number field and add validation to ensure at least one contact method (email/phone) is provided, and that no duplicates exist.

# accounts/forms.py
from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser
from django import forms

class CustomUserCreationForm(UserCreationForm):
    phone_number = forms.CharField(required=False, help_text="Optional. Enter a valid phone number.")

    class Meta:
        model = CustomUser
        fields = ('username', 'email', 'phone_number', 'password1', 'password2')

    def clean(self):
        cleaned_data = super().clean()
        email = cleaned_data.get('email')
        phone_number = cleaned_data.get('phone_number')

        # Make sure user provides at least one contact method
        if not email and not phone_number:
            raise forms.ValidationError("You need to enter either an email address or a phone number.")

        # Check if phone number is already taken (if provided)
        if phone_number and CustomUser.objects.filter(phone_number=phone_number).exists():
            raise forms.ValidationError("This phone number is already registered to another account.")

        return cleaned_data
3. Custom Authentication Backend (The Magic for Multi-Field Login)

Django’s default login only uses usernames. To let users log in with username, email, OR phone number, we need a custom auth backend that checks all three fields against the login input.

# accounts/backends.py
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.db.models import Q

class CustomAuthBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        UserModel = get_user_model()
        try:
            # Look up user by username, email, OR phone number
            user = UserModel.objects.get(
                Q(username=username) | 
                Q(email=username) | 
                Q(phone_number=username)
            )
        except UserModel.DoesNotExist:
            # No user found with any of these fields
            return None
        except UserModel.MultipleObjectsReturned:
            # Safeguard in case of duplicates (our model prevents this, but better safe than sorry)
            user = UserModel.objects.filter(
                Q(username=username) | 
                Q(email=username) | 
                Q(phone_number=username)
            ).first()

        # Verify the password is correct
        if user.check_password(password):
            return user
        return None

    def get_user(self, user_id):
        UserModel = get_user_model()
        try:
            return UserModel.objects.get(pk=user_id)
        except UserModel.DoesNotExist:
            return None

Add this backend to your settings.py so Django uses it:

# settings.py
AUTHENTICATION_BACKENDS = [
    'accounts.backends.CustomAuthBackend',
    'django.contrib.auth.backends.ModelBackend',  # Keep default as fallback
]
4. Set Up Views & URLs

We’ll use Django’s built-in class-based views for registration and login—they’re clean and require minimal code.

# accounts/views.py
from django.views.generic.edit import CreateView
from django.contrib.auth.views import LoginView
from django.urls import reverse_lazy
from .forms import CustomUserCreationForm

class RegisterView(CreateView):
    form_class = CustomUserCreationForm
    success_url = reverse_lazy('login')  # Redirect to login after successful registration
    template_name = 'accounts/register.html'

class CustomLoginView(LoginView):
    template_name = 'accounts/login.html'
    redirect_authenticated_user = True  # Redirect logged-in users away from login page

Now wire up the URLs:

# accounts/urls.py
from django.urls import path
from .views import RegisterView, CustomLoginView

urlpatterns = [
    path('register/', RegisterView.as_view(), name='register'),
    path('login/', CustomLoginView.as_view(), name='login'),
]

Include these in your project’s main urls.py:

# project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('accounts.urls')),
]
5. Basic Template Examples

Here are simple templates to get you started—you’ll want to style them to match Instagram’s look, but this covers the functionality.

Register Template (templates/accounts/register.html)

<!DOCTYPE html>
<html>
<head>
    <title>Sign Up</title>
</head>
<body>
    <h2>Create Your Account</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Sign Up</button>
    </form>
    <p>Already have an account? <a href="{% url 'login' %}">Log In</a></p>
</body>
</html>

Login Template (templates/accounts/login.html)

<!DOCTYPE html>
<html>
<head>
    <title>Log In</title>
</head>
<body>
    <h2>Log In</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Log In</button>
    </form>
    <p>Don't have an account? <a href="{% url 'register' %}">Sign Up</a></p>
</body>
</html>
6. Extra Tips for Instagram-like Polish
  • Email/Phone Verification: Instagram requires users to verify their email—you can add this with custom logic or packages like django-allauth. For phone verification, services like Twilio work great.
  • Password Reset: Extend Django’s default password reset to support both email and phone number (if needed).
  • Form Styling: Ditch the default form.as_p and add CSS to make your forms look clean and modern (like Instagram’s minimal design).
  • Friendly Error Messages: Customize form error messages to be more user-friendly (e.g., "This email is already in use" instead of generic validation text).

内容的提问来源于stack exchange,提问作者Lakshitha Kumara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:08:55