Django - 在多个页面上重用用户注册表单的系统架构

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django - 在多个页面上重用用户注册表单的系统架构相关的知识,希望对你有一定的参考价值。

我正在想办法如何重复使用相同的注册表单并查看多个模板和页面,以及不同的格式。例如。在页面上,在一个模态等。然而,我在找出解决这个问题的最佳实践方面遇到了一些麻烦。我正在积极避免的一件事就是重复自己,但我似乎找不到足够令人满意的解决方案。

目前,我有一个处理用户注册的中央视图,看起来像这样。目前它只能处理在signup_form模板上输出一个表单,但我想将其扩展到索引页面并且能够以模态输出。

Views.py

def signup(request):
    template_name = 'core/authentication/signup_form.html'
    custom_error_list = []
    if request.method == "POST":
        form = SignUpForm(request.POST)
        if form.is_valid():
            #Check for duplciate email
            email = form.cleaned_data.get('email')
            username = form.cleaned_data.get('username')
            if email and User.objects.filter(email=email).exclude(username=username).exists():
                custom_error_list.append("A user with that email already exists")

            else:
                user = form.save(commit=False)
                user.is_active = False
                user.save()
                current_site = get_current_site(request)
                subject = 'Activate your StockPy Account'
                sender = '' #Insert sender address here
                message = render_to_string('core/authentication/account_activation_email.html', {
                    'user': user,
                    'domain': current_site.domain,
                    'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                    'token': account_activation_token.make_token(user)
                })
                user.email_user(subject, message)
                return redirect('authentication:account_activation_sent')
    else:
        form = SignUpForm()
    return render(request, template_name, {'form': form, 'custom_error_list': custom_error_list})

#Activate the user as he/she clicks the email verification link which lead to tihs view
def activate(request, uidb64, token):
    try:
        #Using a [:1] is ad-hoc solution to get rid of the starting 'b' symbol
        uid = force_text(urlsafe_base64_decode(uidb64[1:]))
        user = User.objects.get(pk=uid)
    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None

    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.profile.email_confirmed = True
        user.save()
        login(request, user)
        return redirect(template_name)
    else:
        return render(request, 'core/authentication/account_activation_invalid.html')

forms.py

from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

from django import forms

class LoginForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ['email','password']

class SignUpForm(UserCreationForm):

    email = forms.EmailField(max_length=254, widget=forms.TextInput(attrs={'placeholder': 'Email...', 'class' : 'form-control', 'pattern' : '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$'}))

    class Meta:
        model = User
        fields = ['email', 'username', 'password1', 'password2']

    def __init__(self, *args, **kwargs):
        super(SignUpForm, self).__init__(*args, **kwargs)
        self.fields['username'].widget = forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Username...',
        })
        self.fields['password1'].widget = forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Password...',
            'type': 'password',
        })
        self.fields['password2'].widget = forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Password again...',
            'type': 'password',
        })

我的注册表单目前看起来像这样。

signup_form.html

{% extends 'base.html' %}
{% load static %}
<!-- End Navbar -->
{% block page-header %}
<div class="section section-signup" style="background-image: url({% static 'core/assets/img/bg8.jpg' %}); background-size: cover; background-position: top center; min-height: 700px;">
    <div class="container">
        <div class="row">
            <div class="card card-signup" data-background-color="orange">
                <form class="form" method="POST" action="">
                    {% csrf_token %}
                    <div class="header text-center">
                        <h4 class="title title-up">Sign Up</h4>
                        <div class="social-line">
                            <a href="#twitter" class="btn btn-neutral btn-twitter btn-icon btn btn-round">
                                <i class="fa fa-twitter"></i>
                            </a>
                            <a href="#facebook" class="btn btn-neutral btn-facebook btn-icon btn-lg btn-round">
                                <i class="fa fa-facebook-square"></i>
                            </a>
                            <a href="#google" class="btn btn-neutral btn-google btn-icon btn-round">
                                <i class="fa fa-google-plus"></i>
                            </a>
                        </div>
                    </div>
                    <div class="card-body">
                        <!-- Output error messages -->
                        {% for field in form %}
                            <div style="color:red; list-decorations:none;" class="text-center">
                                {{ field.errors.as_text }}
                            </div>
                        {% endfor %}
                        {% for error in custom_error_list %}
                            <div style="color:red;" class="text-center">
                                * {{ error }}
                            </div>
                        {% endfor %}

                        <!-- Output all fields -->
                        {% for field in form %}
                        <div class="input-group form-group-no-border">
                            <span class="input-group-addon">
                                <i class="now-ui-icons
                                    {% if field.name == 'email' %} ui-1_email-85{% endif %}
                                    {% if field.name == 'username' %} users_circle-08{% endif %}
                                    {% if field.name == 'password1' %} ui-1_lock-circle-open{% endif %}
                                    {% if field.name == 'password2' %} ui-1_lock-circle-open{% endif %}
                                "></i>
                            </span>
                            {{ field }}

                            <!-- Give input box red border if data is not valid -->
                            {% if field.errors %}
                                <script>
                                    var element = document.getElementById("{{ field.id_for_label }}");
                                    element.classList.add("form-control-danger");
                                </script>
                            {% endif %}
                        </div>
                        {% endfor %}

                        <div class="text-center">
                            Already registered? <a href="#" style="color:blue;">Log in here</a>
                        </div>
                        <!-- If you want to add a checkbox to this form, uncomment this code -->
                        <!-- <div class="checkbox">
                            <input id="checkboxSignup" type="checkbox">
                                <label for="checkboxSignup">
                                Unchecked
                                </label>
                            </div> -->
                    </div>
                    <div class="footer text-center">
                        <button type="submit" class="btn btn-neutral btn-round btn-lg">Get Started</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
{% endblock page-header %}

我的index.html的一个小例子片段是我想要实现它的方法。

index.html

<div class="main">
    <div class="section section-about-us">
        <div class="container">
            <div class="col-md-8 ml-auto mr-auto text-center">
                {{ form }}
            </div>
        </div>
    </div>
</div>

我真的试图找到一种顺利的方法来做到这一点,但遗憾的是没有结果。

答案

您似乎已经知道如何在多个模板中实现相同的表单,但是您在避免重复代码时遇到了麻烦。为此,这里有一些建议可以减少在多个页面上复制此表单时遇到的重复次数:

  • 验证表单中的数据而不是您的视图。目前,您正在检查views.py中的重复电子邮件地址。如果您复制了表单,则必须重新编写该代码。相反,为什么不在自定义清理方法中将其移动到forms.py中(请参阅Django docs on custom form cleaning)。
  • 为将要重复的操作编写函数。例如,目前,您正在views.py中向您的用户发送激活电子邮件。在用户/ models.py中编写一个函数更有意义,如send_activation_email().,当你想向用户发送激活电子邮件时,你可以调用user.send_activation_email()而不是复制你的整个激活电子邮件代码块(见Django docs on model methods)。
  • 使用包含标记可避免模板中的重复。如果您发现自己在模板中重复了一段代码,则可以使用Django的包含标记在多个模板中包含一小段HTML。这使您可以在多个位置提供相同的表单,而无需重新编写代码。如果要在不同的页面上对表单进行不同的样式设置,可以将其包装在具有不同ID的DIV中,并使用CSS根据所包含的DIV对表单进行不同的样式设置。(请参阅Django docs on inclusion tags

以上是关于Django - 在多个页面上重用用户注册表单的系统架构的主要内容,如果未能解决你的问题,请参考以下文章

使用 Django 在一个页面上登录和注册表单

Django 在基于类的视图中处理多个表单

在 Django 的一个页面上使用多个表单

如何在具有相同模型的同一 MVC 页面上重用表单?

django项目一:基于django2.2可重用登录与注册模块-Django表单

django项目一:基于django2.2可重用登录与注册模块-Django表单