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

时间:2017-12-24 15:39:44

标签: html django forms architecture

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

目前我有一个处理用户注册的中央视图,看起来像这样。目前它只能处理在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>

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

1 个答案:

答案 0 :(得分:1)

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

  • 验证表单中的数据而不是您的视图。目前,您正在检查views.py中的重复电子邮件地址。如果您复制了表单,则必须重新编写该代码。相反,为什么不在自定义清理方法中将其移动到forms.py中(请参阅Django docs on custom form cleaning)。

  • 为将要重复的操作编写函数。例如,目前,您正在views.py中向您的用户发送激活电子邮件。在user / 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

    < / LI>