利用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)
2017年10月31日 星期二
基本功 - 堆疊
利用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)
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
P.S:此方法為Python2.0之後方法
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' 請確認有無空白,不然會噴錯
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'}),
}
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')
完成
隱藏內建User model help_text 訊息
# form.py
from django.contrib.auth.models import User
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
help_texts = {
'username': None, # 取消掉
}
fields = ('username', 'email', 'password')
完成
2017年10月29日 星期日
Django - Form資料驗證筆記
此筆記將紀錄詳細的資料驗證。
以驗證機器人為例:
新增一個隱藏的欄位來檢驗機器人,如屬性value有值代表是機器人,即發出資料驗證訊息。
使用clean_XXX()來驗證單一欄位
from django import forms
class FormName(forms.Form):
name = forms.CharField()
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
botcatcher = forms.CharField(required=False,
widget=forms.HiddenInput)
def clean_botcatcher(self):
botcatcher = self.cleaned_data['botcatcher']
if len(botcatcher) > 0:
raise forms.ValidationError("Gotcha bot!!!")
return botcatcher
另一種方法是使用validators,可以讓程式更簡短
from django import forms
class FormName(forms.Form):
name = forms.CharField()
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
botcatcher = forms.CharField(required=False,
widget=forms.HiddenInput,
validators = [validators.MaxLengthValidator(0)])
客製驗證,以檢驗開頭必要為z為例:
利用validators客制自己的資料驗證,新增一個method 來寫入檢驗邏輯,成立即發出error訊息。
from django import forms
from django.core import validators
def check_for_z(value):
if value[0].lower() != 'z':
raise forms.ValidationError('Name needs to start with z')
class FormName(forms.Form):
name = forms.CharField(validators=[check_for_z],)
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
驗證再次輸入的email與email欄位是否相符,使用clean()
使用clean()讀取多個欄位
from django import forms
from django.core import validators
class FormName(forms.Form):
name = forms.CharField(validators=[check_for_z],)
email = forms.EmailField()
verify_email = forms.EmailField(label='Enter your email again')
text = forms.CharField(widget=forms.Textarea)
def clean(self):
email = self.cleaned_data.get('email')
vmail = self.cleaned_data.get('verify_email')
if email != vmail:
raise forms.ValidationError("make sure emails match")
以驗證機器人為例:
新增一個隱藏的欄位來檢驗機器人,如屬性value有值代表是機器人,即發出資料驗證訊息。
使用clean_XXX()來驗證單一欄位
from django import forms
class FormName(forms.Form):
name = forms.CharField()
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
botcatcher = forms.CharField(required=False,
widget=forms.HiddenInput)
def clean_botcatcher(self):
botcatcher = self.cleaned_data['botcatcher']
if len(botcatcher) > 0:
raise forms.ValidationError("Gotcha bot!!!")
return botcatcher
另一種方法是使用validators,可以讓程式更簡短
from django import forms
from django.core import validators
class FormName(forms.Form):
name = forms.CharField()
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
botcatcher = forms.CharField(required=False,
widget=forms.HiddenInput,
validators = [validators.MaxLengthValidator(0)])
客製驗證,以檢驗開頭必要為z為例:
利用validators客制自己的資料驗證,新增一個method 來寫入檢驗邏輯,成立即發出error訊息。
from django import forms
from django.core import validators
def check_for_z(value):
if value[0].lower() != 'z':
raise forms.ValidationError('Name needs to start with z')
class FormName(forms.Form):
name = forms.CharField(validators=[check_for_z],)
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
驗證再次輸入的email與email欄位是否相符,使用clean()
使用clean()讀取多個欄位
from django import forms
from django.core import validators
class FormName(forms.Form):
name = forms.CharField(validators=[check_for_z],)
email = forms.EmailField()
verify_email = forms.EmailField(label='Enter your email again')
text = forms.CharField(widget=forms.Textarea)
def clean(self):
email = self.cleaned_data.get('email')
vmail = self.cleaned_data.get('verify_email')
if email != vmail:
raise forms.ValidationError("make sure emails match")
Django - Basic Form筆記
此筆記將實作Basic Form
1.
新增form.py並設定欄位,如下:
from django import forms
class FormName(forms.Form):
name = forms.CharField()
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
2.
新增view
from django.shortcuts import render
from . import form as forms
def for_name_view(request):
form = forms.FormName()
if request.method == 'POST':
form = forms.FormName(request.POST)
if form.is_valid():
print('Validation success!!!')
print("Name: "+form.cleaned_data['name'])
print("Email: "+form.cleaned_data['email'])
print("Text: "+form.cleaned_data['text'])
# 此處之後進行query或是一些邏輯
return render(request, 'basicapp/form_page.html',{'form' : form})
3.
新增template
<form method="POST"> # 大小寫沒差
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Submit">
</form>
4.
設定路由
完成
1.
新增form.py並設定欄位,如下:
from django import forms
class FormName(forms.Form):
name = forms.CharField()
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
2.
新增view
from django.shortcuts import render
from . import form as forms
def for_name_view(request):
form = forms.FormName()
if request.method == 'POST':
form = forms.FormName(request.POST)
if form.is_valid():
print('Validation success!!!')
print("Name: "+form.cleaned_data['name'])
print("Email: "+form.cleaned_data['email'])
print("Text: "+form.cleaned_data['text'])
# 此處之後進行query或是一些邏輯
return render(request, 'basicapp/form_page.html',{'form' : form})
3.
新增template
<form method="POST"> # 大小寫沒差
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Submit">
</form>
4.
設定路由
完成
Django - Model & Admin Interfacel筆記
行前準備
python mange.py migrate
python mange.py makemigratons app
為了讓admin mode可以看到model,必須要在admin.py中註冊
from app.models import Model1, Model2
admin.site.register(Model1)
admin.site.register(Model2)
創立Model
開啟app中的model.py輸入:
class Topic(models.Model):
top_name = models.CharField(max_length=264, unique=True)
def __str__(self):
return self.top_name
class Webpage(models.Model):
topic = models.ForeignKey(Topic)
name = models.CharField(max_length=264, unique=True, verbose_name='名字')
url = models.URLField(unique=True)
def __str__(self):
return self.name
class AccessRecord(models.Model):
name = models.ForeignKey(Webpage)
date = models.DateField()
def __str__(self):
return str(self.date)
from apptwo.models import Topic
print(Topic.objects.all()) # 沒東西
t = Topic(top_name="social network")
t.save()
print(Topic.objects.all()) #出現剛剛新增的social network
quit()
利用superuser帳號登入admin interface
http://127.0.0.1:8000/admin
完成
新增日期, 修改日期
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
python mange.py migrate
python mange.py makemigratons app
為了讓admin mode可以看到model,必須要在admin.py中註冊
from app.models import Model1, Model2
admin.site.register(Model1)
admin.site.register(Model2)
創立Model
開啟app中的model.py輸入:
class Topic(models.Model):
top_name = models.CharField(max_length=264, unique=True)
def __str__(self):
return self.top_name
class Webpage(models.Model):
topic = models.ForeignKey(Topic)
name = models.CharField(max_length=264, unique=True, verbose_name='名字')
url = models.URLField(unique=True)
def __str__(self):
return self.name
class AccessRecord(models.Model):
name = models.ForeignKey(Webpage)
date = models.DateField()
def __str__(self):
return str(self.date)
python mange.py migrate
python mange.py makemigratons app # 必須要和app name相同
python mange.py migrate
python mange.py makemigratons app # 必須要和app name相同
python mange.py migrate
完成以上指令我們進入shell mode確認一下model是否創立成功
python manage.py shell
print(Topic.objects.all()) # 沒東西
t = Topic(top_name="social network")
t.save()
print(Topic.objects.all()) #出現剛剛新增的social network
quit()
接下來將利用admin interface來新增資料,在這之前註冊
# admin.py
from apptwo.models import AccessRecord, Topic, Webpage
admin.site.register(AccessRecord)
admin.site.register(Topic)
admi.site.register(Webpage)
建立superuser
python manage.py createsuperuser
利用superuser帳號登入admin interface
http://127.0.0.1:8000/admin
完成
新增日期, 修改日期
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Django - Form概念筆記
此筆記將介紹Django強大的Input Form功能,以下為基本流程。
1.
新增form.py並定義之,內容類似model
2.
將form.py import views.py,此動作可選兩種方法:
from . import form
from form import FormName
3.
新增新的view給form,如下:
def form_name_view(request):
form = forms.FormName()
return render(request, 'form.html', {'form' : form})
4.
設定urls.py的路由
5.
新增template接應view的form,以及templates資料夾路徑
完成
How to inject the form?
<form method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Submit">
</form>
看了之後可能會有以下問題:
as_p是什麼?
inject 的form 加上as_p
將會被<p>包起來而完整的排好
{% csrf_token %}是什麼?
每當使用form發出http verb都要加上這個,否則form無法運行。此機制是利用django加密好的token來防止資安問題。
cleaned_data是什麼?
form input的資料,可利用form.cleaned_data['name']來讀取
1.
新增form.py並定義之,內容類似model
2.
將form.py import views.py,此動作可選兩種方法:
from . import form
from form import FormName
3.
新增新的view給form,如下:
def form_name_view(request):
form = forms.FormName()
return render(request, 'form.html', {'form' : form})
4.
設定urls.py的路由
5.
新增template接應view的form,以及templates資料夾路徑
完成
How to inject the form?
<form method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Submit">
</form>
看了之後可能會有以下問題:
as_p是什麼?
inject 的form 加上as_p
將會被<p>包起來而完整的排好
{% csrf_token %}是什麼?
每當使用form發出http verb都要加上這個,否則form無法運行。此機制是利用django加密好的token來防止資安問題。
cleaned_data是什麼?
form input的資料,可利用form.cleaned_data['name']來讀取
2017年10月28日 星期六
Django - MTV架構筆記
MTV是Django Models, Templates, Views的縮寫
此筆記將紀錄開發Django app時的步驟
1.
import 要用的models於views.py
2.
進行query於views.py
3.
將query的結果傳到Template
4.
Template去接應Views.py的結果,如果控制流程必須要有收尾的Tag
如:{% endif %}、{% endfor %}
5.
urls.py設定路由
此筆記將紀錄開發Django app時的步驟
1.
import 要用的models於views.py
2.
進行query於views.py
3.
將query的結果傳到Template
4.
Template去接應Views.py的結果,如果控制流程必須要有收尾的Tag
如:{% endif %}、{% endfor %}
5.
urls.py設定路由
Django - 利用Faker產生填充資料
開發系統時,往往都會需要一些填充資料去做測試,此筆記將利用Faker來產生填充資料
pip install Faker
新增py檔於專案跟目錄底下
import os
# Configure settings for project
# Need to run this before calling models from application!
os.environ.setdefault('DJANGO_SETTINGS_MODULE','first_project.settings')
import django
# Import settings
django.setup()
import random
from first_app.models import Topic,Webpage,AccessRecord
from faker import Faker
fakegen = Faker()
topics = ['Search','Social','Marketplace','News','Games']
def add_topic():
t = Topic.objects.get_or_create(top_name=random.choice(topics))[0]
t.save()
return t
def populate(N=5):
'''
Create N Entries of Dates Accessed
'''
for entry in range(N):
# Get Topic for Entry
top = add_topic()
# Create Fake Data for entry
fake_url = fakegen.url()
fake_date = fakegen.date()
fake_name = fakegen.company()
# Create new Webpage Entry
webpg = Webpage.objects.get_or_create(topic=top,url=fake_url,name=fake_name)[0]
# Create Fake Access Record for that page
# Could add more of these if you wanted...
accRec = AccessRecord.objects.get_or_create(name=webpg,date=fake_date)[0]
if __name__ == '__main__':
print("Populating the databases...Please Wait")
populate(20)
print('Populating Complete')
備註:
get_or_create()用於讀取以及寫入,查詢不存在時即寫入
2017年10月25日 星期三
Django - 靜態檔案筆記
本筆記同Template需要新增資料夾、設定settings.py
1.新增名為static的file於專案根目錄(同templates),static裡再創一個images file,放入一張圖片近該資料夾
2.設定settings,新增STATIC_DIR變數如下:
STATIC_DIR = os.path.join(BASE_DIR, "static")
新增STATICFILES_DIRS串列,串列中放入剛剛創的STATIC_DIR變數如下:
STATICFILES_DIRS = [
STATIC_DIR,
]
3.去瀏覽器輸入http://127.0.0.1:8000/static/images/xxx.jpg,將會顯示剛剛放的圖片
4.使用靜態檔案前必須在模板<html>之外加上以下:
{% load staticfiles %}
之後新增img tag
<img src="{% static "images/hp.jpg" %}" alt="me" >
完成
Django的靜態檔案也可以應用在css跟javascript,以css舉例:
1.在static資料夾新增css資料夾並放入css檔
2.模板加入如下
<link rel="stylesheet" type="text/css" href="{% static "css/mycss.css" %}">
完成
設定Media,settings.py新增如下:
MEDIA_DIR = os.path.join(BASE_DIR, 'media').replace('\\', '/')
設定Media,settings.py新增如下:
MEDIA_DIR = os.path.join(BASE_DIR, 'media').replace('\\', '/')
MEDIA_ROOT = MEDIA_DIR
MEDIA_URL = '/media/'
如果settings.py
DEBUG = False
runserver 指令要加上--insecure
如果settings.py
DEBUG = False
runserver 指令要加上--insecure
2017年10月24日 星期二
Django - Templates筆記
這邊要講如何利用Django的Template模板來完成動態網頁
1. 創建Templates資料夾於專案目錄底下
更改settings.py讓Django找到Templates的路徑
2. 賦予一個變數templates資料夾路徑
TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates').replace('\\', '/')
找到TEMPLATE = []中的 DIRS 並貼上變數TEMPLATE_DIR
連接templates資料夾完成
3. 新增模板於templates,如index.html,內容加上模板標籤
# index.html
<h1>Hello index</h1>
{{ insert_me }} # 模板變數
4. 在views的function中,使用render()選擇index.html並傳參數給模板
def index(request):
my_dict = {'insert_me':'Hello I am from views.py'}
return render(request, 'index.html', context = my_dict)
完成
2017年10月23日 星期一
Django - View & Mapping
此筆記將簡略的記錄創造好app之後,該做的事情。
views.py裡新增function
urls.py新增 路徑與app.function做mapping
# views.py
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse('<em>My Second App</em>')
views.py裡新增function
urls.py新增 路徑與app.function做mapping
# views.py
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse('<em>My Second App</em>')
# urls.py
from django.conf.urls import url
from django.contrib import admin
from apptwo import views
urlpatterns = [
url(r'^$', views.index),
url(r'^admin/', admin.site.urls),
]
現在我們已經知道要如何去做到Mapping了,可是會發現一個問題,假設有多個App,每個App都有多個Function,依照上述的設定urls.py將會變的很亂,而Django也有解決此問題的方法。
我們利用include()在project的urls.py中做app的設定,如下:
# first_project/urls.py
from django.conf.urls import url
from django.conf.urls import include # 新增這個
urlpatterns = [
url(r'^first_app/', include('first_app')),
]
完成之後在App目錄底下新增urls.py
# first_app/urls.py
from django.conf.urls import url
from apptwo import views
urlpatterns = [
url(r'^index$', views.index, name='index'),
]
我大概解釋一下,上述設定將每個App的路由交給各自目錄的urls.py處理而不是全部都集中於project的urls.py,結果將會是http://127.0.0.1:8000/first_app/index
first_app/代表執行first_app這個App都要有first_app/,而之後的index代表著first_app中views的index function
有沒有覺得很神奇呢?
訂閱:
文章 (Atom)