2017年11月7日 星期二

Django - Login筆記

新增 LOGIN_URL變數 於 settings.py
新增login template
設定login views
使用decorator
設定urls.py


1. 設定settings LOGIN_URL變數
LOGIN_URL = '/basicapp/user_login'


2. 新增login template
<h1>Login</h1>

<form method="post" action="{% url 'basicapp:user_login' %}" >
{% csrf_token %}
<label for="username">Username:</label>
<input type="text" name="username" placeholder="Enter username...">
<label for="password">Password:</label>
<input type="password" name="password" placeholder="Enter password...">
<input type="submit" name="" value="Login">
</form>


3. 設定views.py

from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required

def user_login(request):

if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')

user = authenticate(username=username, password=password)

if user:
if user.is_active :
login(request, user)
return HttpResponseRedirect(reverse('index'))
else:
return HttpResponse('Account not active')
else:
print('Someone tried to login and failed')
print('Username: {} and password {}'.format(username,password))
return HttpResponse('invalid login details supply')

return render(request, 'basicapp/login.html')



@login_required
def user_logout(request):
logout(request)
return HttpResponseRedirect(reverse('index'))

@login_required
def special(request):
return HttpResponse('You are logged in!')

4. 設定urls.py

完成

判斷登入使用者

不可等入admin mode
is_authenticated

可登入admin mode
is_staff
is_superuser

Javascript - JSON筆記

透過XMLHttpRequest API 載入JSON

宣告XMLHttpRequest物件
var request = new XMLHttpRequest();

設定請求
request.open('GET', requestURL);

設定取得的格式
request.responseType = 'json';
request.send();

處理取得的JSON
request.onload = function() {
  var superHeroes = request.response;
  populateHeader(superHeroes);

}

function populateHeader(jsonObj) {
  var myH1 = document.createElement('h1');
  myH1.textContent = jsonObj['squadName'];
  header.appendChild(myH1);

  var myPara = document.createElement('p');
  myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed'];
  header.appendChild(myPara);
}

參考資訊
https://www.fooish.com/jquery/dom-manipulation.html

HTML5 - BackGround Video

使用mp4為目前最保險的方法

控制播放
<video width="320" height="240" controls>
  <source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>

自動播放
<video width="320" height="240" autoplay>
  <source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>

2017年11月6日 星期一

JQuery - AJAX筆記

本筆記將實作JQuery AJAX + Django 按鈕觸發AJAX


# ajax.html

<!DOCTYPE html>
<html>
<head>
<title>Ajax</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<script>
  $( document ).ready(function() {
$("#btn1").on('click', function () {
$.ajax({
url: 'http://localhost:8000/basic_app/get_json_data/',
type: 'get',
data: {},
dataType: 'json',
timeout: 10000,
success: function(result) {
alert('sucess');
$('#txt1').html(result.result);
},
error: function() {
$('#txt1').html("error");
    }
});
});
});
</script>
</head>
<body>
<h1>Ajax</h1>
<h1 id="txt1" >ready</h1></br>
<button type="button" id="btn1">turn off </button>
</body>
</html>


# views

from django.http import HttpResponse
import json

def get_json_data(request):
    a = {
    'result' : 'success',
    }
    return HttpResponse(json.dumps(a), content_type='application/json')


# urls.py

url(r'^get_json_data/', views.get_json_data,name='get_json_data'),

完成

Cordova筆記

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
function onBodyLoad(){
document.addEventListener("deviceready", onDeviveReady, false);
window.location.href = "http://139.162.96.42";

}

function onDeviveReady(){

}
</script>
<script type="text/javascript" charset="utf-8" src="phonegap-1.3.0.js"></script>
</head>
<body onload="onBodyLoad()">

</body>

</html>



npm install -g cordova

cordova create MyApp

cd MyApp

cordova platform add browser

cordova run browser

2017年11月5日 星期日

Django - User Model & Form

新增與django內建User model關聯的UserProfileInfo model

from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
# Create your models here.

class UserProfileInfo(models.Model):

user = models.OneToOneField(User)

# additional
portfolio_site = models.URLField(blank=True)

profile_pic = models.ImageField(upload_to='profile_pics', blank=True)

def __str__(self):
return self.user.username
使用image前先安裝pillow Image Library

pip install pillow


設定form.py

設定views.py

設定urls.py

makemigrations


2017年11月4日 星期六

Django - Password筆記

此筆記將紀錄使用者認證以及密碼

settting.py

我們將使用以下兩個app才能實作
TEMPLATE_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
]

我將使用bcrypt,使用bcrypt加密密碼是較安全的做法

pip install bcrypt
pip install [argon2] # 如果是1.10以上不需要裝argon2,已經內建於django中


於settings新增

PASSWORD_HASHERS = [
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.Argon2PasswordHasher',
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
]


設定AUTH_PASSWORD_VALIDATORS(可略過)

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'min_length' : 9, #設定密碼至少9碼
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]



Django - Filter & 自製Tag 筆記

此筆記將紀錄如何使用Filter

{{ value | filter : "params" }}
並非全部的filter都用參數

每個單字以大寫開頭
{{ text | title }}

日期格式
{{ mydate | data : "Y-m-d"  }}

大寫text
{{ text | upper }}

小寫
{{ text | lower }}

數字加法,number變數必須要是數字型別
{{ number | add:"2" }}

顯示前n個字元
{{ text | truncatewords:80 }} # 前80


自製Filter


新增templatetags資料夾於app底下,注意不是project而是app


接著於templatetags新增__init__.py 和 tags.py,內容如下:

from django import template

register = template.Library()

def cut(value, arg):
return value.replace(arg,'')

register.filter('cut', cut) # 註冊cut function 成 'cut'

自製Filter,使用decorator

tags.py改成

from django import template

register = template.Library()

@register.filter(name='cut')
def cut(value, arg):
return value.replace(arg,'')


上述設定完就可以使用自製的Filter

{{ text | cut:'cool' }}



自製Tag

import datetime
from django import template

register = template.Library()

@register.simple_tag
def current_time(format_string):
    return datetime.datetime.now().strftime(format_string)

參考:https://docs.djangoproject.com/en/1.11/topics/templates/





2017年11月1日 星期三

Django - Template Inheritance筆記

此筆記將紀錄以DRY為原則的Template Inheritance
{% extends "basic_app/base.html" %}
{% block body_block %}
{% include "includes/_messages.html" %}

# base.html

{% extends "basic_app/base.html" %}

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Base</title>
  </head>
  <body>
    <nav class="navbar navbar-default navbar-static-top">
    </nav>
    <div class="container">
        {% block body_block %}
        {# Anything outside of this will be inherited if you use extend.#}
        {% endblock %}
    </div>
  </body>
</html>

index.html繼承base.html的navbar

{% extends "basic_app/base.html" %}
    {% block body_block%}
        <h1>This is the index.html page</h1>
    {% endblock %}

2017年10月31日 星期二

基本功 - 佇列

利用python實作佇列Queue

class Queue:
    def __init__(self):
        self.items = []

    def enqueue(self, item):
        self.items.insert(0,item)

    def dequeue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)

基本功 - 堆疊

利用python實作stack堆疊

class Stack:
     def __init__(self):
         self.items = []

     def push(self, item):
         self.items.append(item)

     def pop(self):
         return self.items.pop()

     def size(self):
         return len(self.items)

2017年10月30日 星期一

Django - Relative URLs筆記

此筆記將紀錄進階Template技巧

1. Relative URLs


<a href="basicapp/index"> Index </a>
簡化成
<a href="{% url 'basicapp:index' %}">  Index </a>

上例我們設定路由urls.py

# urls.py

from django.conf.urls import url
from basicapp import views

app_name = 'basicapp' # 新增app_name變數
urlpatterns = [
    url(r'^$', views.index, name='index'), # 設定屬性name為index
]

由此可得 {% url 'basicapp:index' %}是如何生成


如果要產生admin頁面相對URLs
{% url 'admin:index' %}


注意:'basicapp:index' 請確認有無空白,不然會噴錯

P.S:此方法為Python2.0之後方法

Django - Model Form筆記

使筆記將紀錄使用Model Form,Model Form直接的與Form做連接,來達成驗證。

操作前務必import以下:
form django import forms
form mapp.models import MyModel

P.S:我們將使用Meta class,實作ModelForm


ModelForm操作案例:

1. show model中全部的欄位,使用__all__

class MyForm(models.ModelForm):
class Meta:
model = MyForm()
fields = "__all__"


2. 排除特定欄位,使用exclude

class MyForm(models.ModelForm):
class Meta:
model = MyForm()
exclude = ["field1", "field2", "field3"]


3. 指定特定欄位
class MyForm(models.ModelForm):
class Meta:
model = MyForm()
fields = ("field1", "field2", "field3")


如想要客制驗證,可以直接寫在Form class裡

class MyForm(models.ModelForm):
        # 加在這 name = froms.CharField(...)
class Meta:
model = MyForm()
fields = ("field1", "field2", "field3")
# 更改Modelform field 屬性
        widgets = {
            'field1': forms.TextInput(attrs={'class': 'textinputclass'}),
            'field2': forms.Textarea(attrs={'class': 'editable medium-editor-textarea postcontent'}),
        }


現在我們將進行ModelForm實作,假設我們已經有一個User Model,現在要製作一個輸入User Model頁面

1. 設定form.py

class MyModelForm(forms.ModelForm):
class Meta():
model = User
fields = '__all__'

2. 設定templates

<form method="POST">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Submit">
</form>

3. 設定views.py

from form import MyModelForm

def model_form_name_view(request):
form = forms.MyModelForm()
if request.method == 'POST':
form = MyModelForm(request.POST)
if form.is_valid():
form.save(commit=True) # exection, same as form.save()
return index(request)
else:
print('ERROR FORM INVALID')

return render(request, 'myapp/model_form_page.html', {'form' : form})

4. 設定urls.py

完成



隱藏內建User model  help_text 訊息

# form.py

from django.contrib.auth.models import User

class UserForm(forms.ModelForm):

password = forms.CharField(widget=forms.PasswordInput())

class Meta():
model = User
help_texts = {
'username': None, # 取消掉
                }
fields = ('username', 'email', 'password')

完成