贊助方

部落格

Apphook 從零開始

翻譯自:BUILDING DJANGO-CMS APPHOOKS

如果你和我一樣懶惰,你一定也不喜歡一樣的 code 寫了一遍又一遍,
那你一定要知道 Django CMS apphook,apphook 可以節省你的開發時間,反覆運用你的原,不用同樣的程式碼又在寫一遍

今天就用我最常客製化的 login 為例,來介紹 Apphook。
首先到 Django CMS 的專案底下,或如果還沒有可以依照底下的步驟快速的新增:
1. 建一個虛擬環境

# 以 conda 建虛擬環境 
conda create -n env python=3.6
conda activate env

# 若已下載過可以跳過這個指令
pip install djangocms-installer

# 新建 django cms 專案
djangocms mysite

接下來到專案目錄下,並執行專案

python manage.py startapp django_login
python manage.py runserver 8080

到 mysite/settings.py 中,把 'django_login' 加進 INSTALLED_APPS 中
再到 mysite/urls.py 中新增以下程式碼,新增 /login 頁面

from django.contrib.auth import views as auth_views

url(r'^en/login/$', auth_views.login, {'template_name': 'registration/login.html'})

login 這個頁面就會使用放在 registration 資料夾裡面的 login.html 當作 template。
以下是我們的 login.html

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
   <div class="login-page">
  <div class="form">
    <form method="POST" class="login-form">
        {% csrf_token %}
      <input type="text" name="username" placeholder="username"/>
      <input type="password" name="password" placeholder="password"/>
      <button type="submit">login</button>
      <p class="message">Not registered? <a href="/register/">Create an account</a></p>
    </form>
  </div>
</div>
</body>

<style>@import url(https://fonts.googleapis.com/css?family=Roboto:300);

.login-page {
  width: 360px;
  padding: 8% 0 0;
  margin: auto;
}
.form {
  position: relative;
  z-index: 1;
  background: #FFFFFF;
  max-width: 360px;
  margin: 0 auto 100px;
  padding: 45px;
  text-align: center;
  box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
}
.form input {
  font-family: "Roboto", sans-serif;
  outline: 0;
  background: #f2f2f2;
  width: 100%;
  border: 0;
  margin: 0 0 15px;
  padding: 15px;
  box-sizing: border-box;
  font-size: 14px;
}
.form button {
  font-family: "Roboto", sans-serif;
  text-transform: uppercase;
  outline: 0;
  background: #4CAF50;
  width: 100%;
  border: 0;
  padding: 15px;
  color: #FFFFFF;
  font-size: 14px;
  -webkit-transition: all 0.3 ease;
  transition: all 0.3 ease;
  cursor: pointer;
}
.form button:hover,.form button:active,.form button:focus {
  background: #43A047;
}
.form .message {
  margin: 15px 0 0;
  color: #b3b3b3;
  font-size: 12px;
}
.form .message a {
  color: #4CAF50;
  text-decoration: none;
}
.form .register-form {
  display: none;
}
.container {
  position: relative;
  z-index: 1;
  max-width: 300px;
  margin: 0 auto;
}
.container:before, .container:after {
  content: "";
  display: block;
  clear: both;
}
.container .info {
  margin: 50px auto;
  text-align: center;
}
.container .info h1 {
  margin: 0 0 15px;
  padding: 0;
  font-size: 36px;
  font-weight: 300;
  color: #1a1a1a;
}
.container .info span {
  color: #4d4d4d;
  font-size: 12px;
}
.container .info span a {
  color: #000000;
  text-decoration: none;
}
.container .info span .fa {
  color: #EF3B3A;
}
body {
  background: #76b852; /* fallback for old browsers */
  background: -webkit-linear-gradient(right, #76b852, #8DC26F);
  background: -moz-linear-gradient(right, #76b852, #8DC26F);
  background: -o-linear-gradient(right, #76b852, #8DC26F);
  background: linear-gradient(to left, #76b852, #8DC26F);
  font-family: "Roboto", sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}</style>


</html>

在 settings.py 中指定登入後的導頁:

LOGIN_REDIRECT_URL = '/'

新增 logout,在 urls.py 新增:

url(r'^logout/$', auth_views.logout)

並且新增 registration/logged_out.html 檔案:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    You have successfully logged out.
    <a href="/">Home</a>
</body>
</html>

接下來,為了註冊,在 mysite/urls.py 新增 url:

from django.conf.urls import url, include
from django.contrib import admin
from .views import home, register
urlpatterns = [

    url(r'^register/', register),
]

因為使用了 django register 的 view,所以建一個資料 django_login,底下新增 forms.py 檔案,檔案內容如下:

from django import forms
class UserRegistrationForm(forms.Form):
    username = forms.CharField(
        required = True,
        label = 'Username',
        max_length = 32
    )
    email = forms.CharField(
        required = True,
        label = 'Email',
        max_length = 32,
    )
    password = forms.CharField(
        required = True,
        label = 'Password',
        max_length = 32,
        widget = forms.PasswordInput()
    )

在新增 django_login/view.py,才可以讓使用者填入資料

from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login
from django.http import HttpResponseRedirect
from django import forms
from .forms import UserRegistrationForm
# Create your views here.

def register(request):
    if request.method == 'POST':
        form = UserRegistrationForm(request.POST)
        if form.is_valid():
            userObj = form.cleaned_data
            username = userObj['username']
            email =  userObj['email']
            password =  userObj['password']
            if not (User.objects.filter(username=username).exists() or User.objects.filter(email=email).exists()):
                User.objects.create_user(username, email, password)
                user = authenticate(username = username, password = password)
                login(request, user)
                return HttpResponseRedirect('/')
            else:
                raise forms.ValidationError('Looks like a username with that email or password already exists')
    else:
        form = UserRegistrationForm()

    return render(request, 'django_login/register.html', {'form' : form})

在這個 view 之中,我們判斷 request 是不是 POST,並且建立了 UserRegistrationForm 的表單。
接下來我們還要新增 djnago_login/register.html,內容如下:

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
   <div class="login-page">
  <div class="form">
    <form method="POST" class="register-form">
        {% csrf_token %} {{ form.as_p }}

      <button>create</button>
      <p class="message">Already registered? <a href="/login/">Sign In</a></p>
    </form>
  </div>
</div>
</body>

<style>@import url(https://fonts.googleapis.com/css?family=Roboto:300);

.login-page {
  width: 360px;
  padding: 8% 0 0;
  margin: auto;
}
.form {
  position: relative;
  z-index: 1;
  background: #FFFFFF;
  max-width: 360px;
  margin: 0 auto 100px;
  padding: 45px;
  text-align: center;
  box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
}
.form input {
  font-family: "Roboto", sans-serif;
  outline: 0;
  background: #f2f2f2;
  width: 100%;
  border: 0;
  margin: 0 0 15px;
  padding: 15px;
  box-sizing: border-box;
  font-size: 14px;
}
.form button {
  font-family: "Roboto", sans-serif;
  text-transform: uppercase;
  outline: 0;
  background: #4CAF50;
  width: 100%;
  border: 0;
  padding: 15px;
  color: #FFFFFF;
  font-size: 14px;
  -webkit-transition: all 0.3 ease;
  transition: all 0.3 ease;
  cursor: pointer;
}
.form button:hover,.form button:active,.form button:focus {
  background: #43A047;
}
.form .message {
  margin: 15px 0 0;
  color: #b3b3b3;
  font-size: 12px;
}
.form .message a {
  color: #4CAF50;
  text-decoration: none;
}
.form .register-form {
  display: true;
}
.container {
  position: relative;
  z-index: 1;
  max-width: 300px;
  margin: 0 auto;
}
.container:before, .container:after {
  content: "";
  display: block;
  clear: both;
}
.container .info {
  margin: 50px auto;
  text-align: center;
}
.container .info h1 {
  margin: 0 0 15px;
  padding: 0;
  font-size: 36px;
  font-weight: 300;
  color: #1a1a1a;
}
.container .info span {
  color: #4d4d4d;
  font-size: 12px;
}
.container .info span a {
  color: #000000;
  text-decoration: none;
}
.container .info span .fa {
  color: #EF3B3A;
}
body {
  background: #76b852; /* fallback for old browsers */
  background: -webkit-linear-gradient(right, #76b852, #8DC26F);
  background: -moz-linear-gradient(right, #76b852, #8DC26F);
  background: -o-linear-gradient(right, #76b852, #8DC26F);
  background: linear-gradient(to left, #76b852, #8DC26F);
  font-family: "Roboto", sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}</style>

<script>
    $('.message a').click(function(){
   $('form').animate({height: "toggle", opacity: "toggle"}, "slow");
});
</script>

</html>

現在,我們必須使用 CMSApp 讓 CMS 知道如何管理,
在 django_login 的目錄下新增 cms_app.py:

from cms.app_base import CMSApp
from cms.apphook_pool import apphook_pool
from django.utils.translation import ugettext_lazy as _


class django_login(CMSApp):
    app_name = "django_login"
    name = _("LOGIN")

    def get_urls(self, page=None, language=None, **kwargs):
        return ["django_login.urls"]


apphook_pool.register(django_login)  # register the application

這樣就完成了!你可去看看。
注意,頁面需要 publish 才會有效 可以到這裡獲得完整範例

點擊立即下載此篇文章 PDF

稍後下載閱讀,或與好友分享


討論區

尚未有留言,搶頭香吧!

討論區