หมายเหตุ
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลอง ลงชื่อเข้าใช้หรือเปลี่ยนไดเรกทอรีได้
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลองเปลี่ยนไดเรกทอรีได้
บทช่วยสอนนี้จะสํารวจวิธีการเริ่มต้นใช้งานเว็บแอปพลิเคชัน Microsoft Advertising โดยใช้ Bing Ads Python SDK, Visual Studio Code IDE และเฟรมเวิร์กเว็บ Django
บทช่วยสอนนี้ไม่ได้สํารวจรายละเอียดต่าง ๆ เกี่ยวกับ Django เองเช่นทํางานกับแบบจําลองข้อมูลและสร้างอินเทอร์เฟซการดูแลระบบ สําหรับคําแนะนําเกี่ยวกับแง่มุมเหล่านั้น โปรดดูเอกสารประกอบของ Django สําหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการทํางานกับ Django ในเทอร์มินัล VS Code ตัวแก้ไข และตัวแก้ไขจุดบกพร่อง ดูใช้ Django ใน Visual Studio Code บทช่วยสอนนี้ยืมอย่างมากจากคําแนะนําในการตั้งค่าใน ใช้ Django ใน Visual Studio Code
ภาพรวมของแอปพลิเคชันบนเว็บตัวอย่าง
ในตอนท้ายของบทช่วยสอนนี้คุณจะมีแอปพลิเคชันบนเว็บที่ทํางานอยู่ http://localhost ซึ่งจะรับรองความถูกต้องของข้อมูลประจําตัวผู้ใช้ Microsoft Advertising ของคุณและแสดงข้อมูลผู้ใช้และบัญชีผู้ใช้ของคุณ จากนั้นคุณสามารถเพิ่มผู้ใช้เว็บแอปพลิเคชันหลายรายซึ่งสามารถเปิดใช้งานการเข้าถึงแอปพลิเคชันของคุณเพื่อใช้ข้อมูลประจําตัว Microsoft Advertising ของพวกเขา แอปพลิเคชันบนเว็บนี้มีการแมปผู้ใช้เว็บแอปพลิเคชันหนึ่งต่อหนึ่งรายการ เช่น ContosoUser กับผู้ใช้ Microsoft Advertising สําหรับข้อมูลเกี่ยวกับวิธีการปรับเปลี่ยนแบบจําลองข้อมูล โปรดดู เอกสารประกอบ Django สําหรับข้อมูลเพิ่มเติม ถ้าผู้ใช้แอปพลิเคชันบนเว็บของคุณเปิดใช้งานการเข้าถึงบัญชี Microsoft Advertising ด้วยบัญชี Microsoft โทเค็นรีเฟรชจะถูกเก็บไว้ในฐานข้อมูล SQL Lite บนเว็บเซิร์ฟเวอร์ของคุณ
ข้อกำหนดเบื้องต้น
คุณจะต้องมี Visual Studio Code ที่ติดตั้งเพื่อทําตามบทช่วยสอนนี้ เมื่อต้องการเรียกใช้เว็บแอป Django คุณสามารถใช้ Visual Studio Community หรือ Visual Studio Professional ได้ อย่างไรก็ตาม ขั้นตอนการตั้งค่าจะแตกต่างจากขั้นตอนในบทช่วยสอนนี้
คุณจะต้องติดตั้ง Python 3 จาก python.org โดยทั่วไปให้ใช้ปุ่ม ดาวน์โหลด Python 3.7.0 ที่ปรากฏเป็นอันดับแรกบนหน้า (หรือเวอร์ชันใดก็ตามเป็นเวอร์ชันล่าสุด) บน Windows ตรวจสอบให้แน่ใจว่าตําแหน่งของตัวแปล Python รวมอยู่ในตัวแปรสภาพแวดล้อม PATH ของคุณ คุณสามารถตรวจสอบได้โดยเรียกใช้ path ที่พรอมต์คําสั่ง ถ้าโฟลเดอร์ของตัวแปล Python ไม่รวมอยู่ ให้เปิดการตั้งค่า Windows ค้นหา "สภาพแวดล้อม" เลือก แก้ไขตัวแปรสภาพแวดล้อมสําหรับบัญชีของคุณ แล้วแก้ไขตัวแปร เส้นทาง เพื่อรวมโฟลเดอร์นั้น
คุณจะต้อง ติดตั้งBing Ads Python SDK และบทช่วยสอนนี้จะแนะนําคุณเกี่ยวกับการติดตั้ง
คุณจะต้องมี เฟรมเวิร์กเว็บ Django ที่ติดตั้งเพื่อปรับใช้แอปพลิเคชันภายในเครื่องและบทช่วยสอนนี้จะแนะนําคุณเกี่ยวกับการติดตั้ง
คุณจะต้องมีผู้ใช้อย่างน้อยหนึ่งรายที่มีข้อมูลประจําตัว Microsoft Advertising และโทเค็นนักพัฒนา
คุณจะต้องลงทะเบียนแอปพลิเคชันและจดบันทึก ID ไคลเอ็นต์ (ID แอปพลิเคชันที่ลงทะเบียน) และข้อมูลลับของลูกค้า (รหัสผ่านที่ลงทะเบียน) คุณจะต้องลงทะเบียนเว็บแอป (ไม่ใช่แบบดั้งเดิม) สําหรับตัวอย่างนี้ คุณจะถูกขอให้ลงทะเบียน URL การเปลี่ยนเส้นทางอย่างน้อยหนึ่งรายการ และสําหรับบทช่วยสอนนี้ คุณควรลงทะเบียนhttp://localhost/callback คุณควรใช้ https เมื่อปรับใช้กับเซิร์ฟเวอร์การผลิตแทน สําหรับรายละเอียดเพิ่มเติมเกี่ยวกับการลงทะเบียนแอปพลิเคชันและโฟลว์การให้สิทธิ์รหัสการให้สิทธิ์ โปรดดูการรับรองความถูกต้องด้วย OAuth
บทช่วยสอนนี้ได้รับการพัฒนาบน Windows แม้ว่า Windows ไม่จําเป็นต้องเรียกใช้ตัวอย่าง แต่ขั้นตอนบางอย่างด้านล่างจะแตกต่างกันถ้าคุณใช้ระบบปฏิบัติการอื่น เช่น Linux หรือ MacOS
สร้างสภาพแวดล้อมของโครงการสําหรับ Django
ในส่วนนี้ คุณสร้างสภาพแวดล้อมเสมือนที่มีการติดตั้ง Django การใช้สภาพแวดล้อมเสมือนจะหลีกเลี่ยงการติดตั้ง Django ลงในสภาพแวดล้อม Python ส่วนกลาง และช่วยให้คุณสามารถควบคุมไลบรารีที่ใช้ในแอปพลิเคชันได้อย่างแท้จริง
บนระบบไฟล์ของคุณ สร้างโฟลเดอร์โครงการสําหรับบทช่วยสอนนี้ เช่น
hello_djangoในโฟลเดอร์ เปิด
hello_djangoPowershell หรือเชลล์สคริปต์ที่คุณชื่นชอบ และใช้คําสั่งต่อไปนี้เพื่อสร้างสภาพแวดล้อมเสมือนที่มีenvชื่อตามตัวแปลปัจจุบันของคุณ:py -3 -m venv envเปิด
hello_djangoโฟลเดอร์โครงการใน VS Code โดยการcode .เรียกใช้ หรือโดยการเรียกใช้ VS Code และใช้คําสั่งเปิดโฟลเดอร์ไฟล์>
ในรหัส VS เปิด Command Palette (ดู>ชุดคําสั่ง หรือ
Ctrl+Shift+P) จากนั้นเลือก Python: เลือกคําสั่งตัวแปลคําสั่งจะแสดงรายการของตัวแปลที่พร้อมใช้งานซึ่ง VS Code สามารถค้นหาได้โดยอัตโนมัติ รายการของคุณจะแตกต่างกัน ถ้าคุณไม่เห็นตัวแปลที่ต้องการ ให้ดู การกําหนดค่าสภาพแวดล้อม Python จากรายการ ให้เลือกสภาพแวดล้อมเสมือนในโฟลเดอร์โครงการของคุณที่เริ่มต้นด้วย
./envหรือ.\env:
เรียกใช้ เทอร์มินัล: เทอร์มินัลใหม่ (
Ctrl+Shift+ `) จาก Command Palette ซึ่งสร้างเทอร์มินัลและเปิดใช้งานสภาพแวดล้อมเสมือนโดยอัตโนมัติโดยการเรียกใช้สคริปต์การเปิดใช้งานหมายเหตุ
บน Windows หากชนิดเทอร์มินัลเริ่มต้นของคุณคือ PowerShell คุณอาจเห็นข้อผิดพลาดที่ไม่สามารถเรียกใช้ activate.ps1 ได้เนื่องจากสคริปต์ที่เรียกใช้ถูกปิดใช้งานบนระบบ ข้อผิดพลาดควรมีลิงก์สําหรับข้อมูลเกี่ยวกับวิธีการอนุญาตสคริปต์ มิฉะนั้น ให้ใช้ เทอร์มินัล: เลือก Shell ค่าเริ่มต้น เพื่อตั้งค่าเริ่มต้นที่คุณต้องการ
สภาพแวดล้อมที่เลือกจะปรากฏที่มุมล่างซ้ายของแถบสถานะ VS Code โปรดสังเกตตัวบ่งชี้ (venv) ที่บอกคุณว่า คุณกําลังใช้สภาพแวดล้อมเสมือน:
ติดตั้ง Django ในสภาพแวดล้อมเสมือนผ่าน pip ใน VS Code Terminal:
python -m pip install djangoติดตั้ง Bing Ads Python SDK ในสภาพแวดล้อมเสมือนผ่าน pip ใน VS Code Terminal:
python -m pip install bingads
ตอนนี้คุณมีสภาพแวดล้อมเสมือนในตัวที่พร้อมสําหรับการเขียน Django และรหัส Microsoft Advertising
สร้างและเรียกใช้แอป Django
ในคําศัพท์ Django "โครงการ Django" ประกอบด้วยไฟล์การกําหนดค่าระดับไซต์หลายไฟล์พร้อมกับ "แอป" อย่างน้อยหนึ่งรายการที่คุณปรับใช้กับโฮสต์เว็บเพื่อสร้างแอปพลิเคชันบนเว็บแบบเต็ม โครงการ Django สามารถมีหลายแอป ซึ่งโดยทั่วไปแล้วแต่ละแอปจะมีฟังก์ชันอิสระในโครงการ และแอปเดียวกันสามารถอยู่ในหลายโครงการ Django ได้ แอปสําหรับส่วนของแอปเป็นเพียงแพ็คเกจ Python ที่เป็นไปตามแบบแผนบางอย่างที่ Django คาดหวัง
หากต้องการสร้างแอป Django จําเป็นต้องสร้างโครงการ Django ก่อนเพื่อทําหน้าที่เป็นคอนเทนเนอร์สําหรับแอป จากนั้นสร้างแอปเอง สําหรับวัตถุประสงค์ทั้งสองอย่าง คุณใช้โปรแกรม django-adminอรรถประโยชน์การดูแลระบบ Django ซึ่งได้รับการติดตั้งเมื่อคุณติดตั้งแพคเกจ Django
สร้างโครงการ Django
ใน VS Code Terminal ที่เปิดใช้งานสภาพแวดล้อมเสมือนของคุณ ให้เรียกใช้คําสั่งต่อไปนี้:
django-admin startproject web_project .คําสั่งนี้
startprojectถือว่า (โดยการใช้.ที่ส่วนท้าย) ที่โฟลเดอร์ปัจจุบันคือโฟลเดอร์โครงการของคุณ และสร้างสิ่งต่อไปนี้ภายใน:manage.py: โปรแกรมอรรถประโยชน์การดูแลบรรทัดคําสั่ง Django สําหรับโครงการ คุณเรียกใช้คําสั่งการดูแลสําหรับโครงการโดยใช้python manage.py <command> [options]โฟลเดอร์ย่อยที่
web_projectชื่อ ซึ่งประกอบด้วยแฟ้มต่อไปนี้:-
__init__.py: ไฟล์เปล่าที่บอก Python ว่าโฟลเดอร์นี้เป็นแพคเกจ Python -
wsgi.py: จุดเข้าใช้งานสําหรับเว็บเซิร์ฟเวอร์ที่เข้ากันได้กับ WSGI เพื่อให้บริการโครงการของคุณ โดยทั่วไปแล้ว คุณจะปล่อยไฟล์นี้ไว้เหมือนเดิมเนื่องจากมีจุดเชื่อมต่อสําหรับเว็บเซิร์ฟเวอร์ที่ใช้งานจริง -
settings.py: ประกอบด้วยการตั้งค่าสําหรับโครงการ Django ที่คุณปรับเปลี่ยนในการพัฒนาเว็บแอป -
urls.py: มีสารบัญสําหรับโครงการ Django ซึ่งคุณปรับเปลี่ยนในการพัฒนา
-
เมื่อต้องการตรวจสอบโครงการ Django ตรวจสอบให้แน่ใจว่าสภาพแวดล้อมเสมือนของคุณเปิดใช้งานแล้ว จากนั้นเริ่มเซิร์ฟเวอร์การพัฒนาของ Django โดยใช้คําสั่ง
python manage.py runserverเซิร์ฟเวอร์ทํางานบนพอร์ตเริ่มต้น 8000 และคุณเห็นผลลัพธ์ดังต่อไปนี้ในหน้าต่างผลลัพธ์เทอร์มินัล VS Code:Performing system checks... System check identified no issues (0 silenced). You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. October 18, 2018 - 05:38:23 Django version 2.1.2, using settings 'web_project.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.เมื่อคุณเรียกใช้เซิร์ฟเวอร์เป็นครั้งแรก จะสร้างฐานข้อมูล SQLite เริ่มต้นในไฟล์
db.sqlite3ซึ่งโดยทั่วไปมีไว้สําหรับการพัฒนา แต่สามารถใช้ในการผลิตสําหรับเว็บแอปปริมาณน้อยได้ นอกจากนี้เว็บเซิร์ฟเวอร์ในตัวของ Django มีไว้สําหรับการพัฒนาท้องถิ่นเท่านั้น อย่างไรก็ตาม เมื่อคุณปรับใช้กับโฮสต์เว็บ Django จะใช้เว็บเซิร์ฟเวอร์ของโฮสต์แทน โมดูลwsgi.pyในโครงการ Django ดูแลการติดเข้ากับเซิร์ฟเวอร์การผลิตหากคุณต้องการใช้พอร์ตที่แตกต่างจากค่าเริ่มต้น 8000 เพียงระบุหมายเลขพอร์ตในบรรทัดคําสั่ง เช่น
python manage.py runserver 5000Ctrl+clickhttp://127.0.0.1:8000/URL ในหน้าต่างผลลัพธ์เทอร์มินัล VS Code เพื่อเปิดเบราว์เซอร์เริ่มต้นของคุณไปยังที่อยู่นั้น ถ้ามีการติดตั้ง Django อย่างถูกต้องและโครงการถูกต้อง คุณจะเห็นหน้าเริ่มต้นที่แสดงด้านล่าง หน้าต่าง VS Code Output ยังแสดงบันทึกของเซิร์ฟเวอร์
เมื่อคุณทําเสร็จแล้ว ให้ปิดหน้าต่างเบราว์เซอร์และหยุดเซิร์ฟเวอร์ใน VS Code โดยใช้
Ctrl+Cตามที่ระบุในหน้าต่างผลลัพธ์เทอร์มินัล VS Code
สร้างแอป Django สําหรับการโฆษณาของ Microsoft
ใน VS Code Terminal ที่เปิดใช้งานสภาพแวดล้อมเสมือนให้เรียกใช้คําสั่งของโปรแกรมอรรถประโยชน์
startappการดูแลระบบในโฟลเดอร์โครงการของคุณ (ที่มีmanage.py):python manage.py startapp appคําสั่งสร้างโฟลเดอร์ที่เรียกว่า
appที่ประกอบด้วยแฟ้มโค้ดและโฟลเดอร์ย่อยหนึ่งโฟลเดอร์ จากสิ่งเหล่านี้ คุณทํางานviews.pyด้วยบ่อย (ที่มีฟังก์ชันที่กําหนดหน้าในเว็บแอปของคุณ) และmodels.py(ที่มีคลาสที่กําหนดวัตถุข้อมูลของคุณ) โฟลเดอร์migrationsนี้ถูกใช้โดยโปรแกรมอรรถประโยชน์การดูแลระบบของ Django เพื่อจัดการเวอร์ชันฐานข้อมูลตามที่อธิบายไว้ในบทช่วยสอนนี้ในภายหลัง นอกจากนี้ยังมีไฟล์apps.py(การกําหนดค่าแอป)admin.py(สําหรับการสร้างอินเทอร์เฟซการดูแลระบบ) และtests.py(สําหรับการทดสอบหน่วย) ซึ่งไม่ครอบคลุมที่นี่ภายใน
app/settings.pyเพิ่มโค้ดต่อไปนี้ และตั้งค่า CLIENT_IDCLIENT_SECRETDEVELOPER_TOKEN และ สภาพแวดล้อม ของคุณเอง""" Bing Ads API settings Edit with your credentials. """ REDIRECTION_URI = "http://localhost:8000/callback" CLIENT_ID = "ClientIdGoesHere" # Your registered App ID CLIENT_SECRET="ClientSecretGoesHere" # Your registered App Password DEVELOPER_TOKEN = "DeveloperTokenGoesHere" # Your production developer token ENVIRONMENT = 'production' API_VERSION=13ภายใน
app/settings.pyเพิ่มappไปยังรายการแอปที่ติดตั้งINSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app', ]ในเทอร์มินัล VS Code ให้
app/static/appสร้างโฟลเดอร์ และapp/templates/app:(env) PS C:\dev\hello_django> mkdir app/static/app (env) PS C:\dev\hello_django> mkdir app/templates/appapp/static/appภายในโฟลเดอร์ สร้างไฟล์ใหม่ที่มีชื่อว่า site.css และเพิ่มเนื้อหาต่อไปนี้.message { font-weight: 600; color: blue; } .message_list th,td { text-align: left; padding-right: 15px; } .navbar { background-color: lightslategray; font-size: 1em; font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; color: white; padding: 8px 5px 8px 5px; } .navbar a { text-decoration: none; color: inherit; } .navbar-brand { font-size: 1.2em; font-weight: 600; } .navbar-item { font-variant: small-caps; margin-left: 30px; } .body-content { padding: 5px; font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } input[name=message] { width: 80%; }app/templates/appภายในโฟลเดอร์ สร้างไฟล์index.htmlด้วยเนื้อหาด้านล่าง{% extends "app/layout.html" %} {% block content %} {% if errors %} <div class="jumbotron"> <section id="errors"> <h1>Errors occurred in your last request to Bing Ads API.</h1> <table class="message_list"> <tr> <th>Code</th> <th>ErrorCode</th> <th>Message</th> </tr> {% for error in errors %} <tr> <td>{{ error.Code }}</td> <td>{{ error.ErrorCode }}</td> <td>{{ error.Message }}</td> </tr> {% endfor %} </table> </section> </div> {% endif %} {% if user.is_authenticated %} {% if bingadsuser %} <div class="jumbotron"> <section id="enabled"> <h1>Your credentials have access to Microsoft Advertising.</h1> <table class="message_list"> <tr> <th>Id</th> <th>UserName</th> <th>First Name</th> <th>Last Name</th> </tr> <tr> <td>{{ bingadsuser.Id }}</td> <td>{{ bingadsuser.UserName }}</td> <td>{{ bingadsuser.Name.FirstName }}</td> <td>{{ bingadsuser.Name.LastName }}</td> </tr> </table> </section> </div> <div class="jumbotron"> <section id="revoke"> <p class="lead">Click here to revoke access for this app to your Microsoft Advertising accounts. You will then be able to login with a different Microsoft Advertising user. </p> <form id="revokeForm" action="/revoke" method="post" class="navbar-left"> {% csrf_token %} <p><a href="javascript:document.getElementById('revokeForm').submit()" class="btn btn-primary btn-large">Delete Refresh Token</a></p> </form> </section> </div> <div class="jumbotron"> <section id="accounts"> <h1>Account Details</h1> <table class="message_list"> <thead> <tr> <th>Id</th> <th>Name</th> </tr> </thead> <tbody> {% for account in accounts %} <tr> <td>{{ account.Id }}</td> <td>{{ account.Name }}</td> </tr> {% endfor %} </tbody> </table> </section> </div> {% else %} <div class="jumbotron"> <section id="enable"> <h1>Enable Microsoft Advertising Access</h1> <p class="lead"> You are logged into the Django web application, but not yet signed in with your Microsoft Advertising credentials. You can sign in with Microsoft Advertising credentials below. </p> </section> </div> <div> <div class="col-md-6"> <section id="socialLoginForm"> <h1>Microsoft Account Login</h1> <p class="lead"> Click here to authenticate your Microsoft Account. If you don't have Microsoft Advertising credentials, you can go to the <a href="https://ads.microsoft.com/customer/Signup.aspx">Microsoft Advertising Sign Up</a> page. </p> <p><a href="/callback" class="btn btn-primary btn-large">Authenticate Microsoft Account »</a></p> </section> </div> </div> {% endif %} {% else %} <div class="jumbotron"> <div class="col-md-6"> <section id="socialLoginForm"> <h1>Microsoft Advertising Example Web Application</h1> <p class="lead"> Before you can provide your Microsoft Advertising user credentials and access Microsoft Advertising data, you must <a href="{% url 'login' %}">login</a> to the Django web application. </p> <p class="lead">Use your site's Django admin portal to add web app users.</p> <p><a href="/admin" class="btn btn-primary btn-large">Django Admin »</a></p> </section> </div> </div> {% endif %} <div> <div class="col-md-4"> <h2>Get Started Using Python with Bing Ads API</h2> <p>The Bing Ads Python Software Development Kit (SDK) simplifies workflows such as OAuth authentication and report file parsing.</p> <p><a class="btn btn-default" href="https://learn.microsoft.com/advertising/guides/get-started-python">Learn more »</a></p> </div> <div class="col-md-4"> <h2>Django</h2> <p>Django is a free web framework for building Web sites and Web applications using HTML, CSS and JavaScript.</p> <p><a class="btn btn-default" href="https://www.djangoproject.com/">Learn more »</a></p> </div> <div class="col-md-4"> <h2>Microsoft Azure</h2> <p>You can publish your web app to Microsoft Azure. Find out how you can host your application with a free trial today.</p> <p><a class="btn btn-default" href="https://azure.microsoft.com">Learn more »</a></p> </div> </div> {% endblock %} {% block scripts %} {% load static %} <link rel="stylesheet" type="text/css" href="{% static 'app/site.css' %}"/> {% endblock %}app/templates/appภายในโฟลเดอร์ สร้างไฟล์layout.htmlด้วยเนื้อหาด้านล่าง<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{ title }} - My Django Application</title> {% load static %} <link rel="stylesheet" type="text/css" href="{% static 'app/site.css' %}"/> <script src="{% static 'app/scripts/modernizr-2.6.2.js' %}"></script> </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a href="/" class="navbar-brand">Microsoft Advertising App via Django</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="{% url 'home' %}">Home</a></li> </ul> {% include 'app/loginpartial.html' %} </div> </div> </div> <div class="container body-content"> {% block content %}{% endblock %} <hr/> <footer> <p>© {{ year }} - My Django Application</p> </footer> </div> {% block scripts %}{% endblock %} </body> </html>app/templates/appภายในโฟลเดอร์ สร้างไฟล์login.htmlด้วยเนื้อหาด้านล่าง{% extends "app/layout.html" %} {% block content %} <h2>{{ title }}</h2> <div class="row"> <div class="col-md-8"> <section id="loginForm"> <form action="." method="post" class="form-horizontal"> {% csrf_token %} <h4>Use a local account to log in.</h4> <hr /> <div class="form-group"> <label for="id_username" class="col-md-2 control-label">User name</label> <div class="col-md-10"> {{ form.username }} </div> </div> <div class="form-group"> <label for="id_password" class="col-md-2 control-label">Password</label> <div class="col-md-10"> {{ form.password }} </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="hidden" name="next" value="/" /> <input type="submit" value="Log in" class="btn btn-default" /> </div> </div> {% if form.errors %} <p class="validation-summary-errors">Please enter a correct user name and password.</p> {% endif %} </form> </section> </div> </div> {% endblock %} {% block scripts %} {% load static %} <link rel="stylesheet" type="text/css" href="{% static 'app/site.css' %}"/> {% endblock %}app/templates/appภายในโฟลเดอร์ สร้างไฟล์loginpartial.htmlด้วยเนื้อหาด้านล่าง{% if user.is_authenticated %} <form id="logoutForm" action="/applogout" method="post" class="navbar-right"> {% csrf_token %} <ul class="nav navbar-nav navbar-right"> <li><span class="navbar-brand">Hello {{ user.username }}!</span></li> <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li> </ul> </form> {% else %} <ul class="nav navbar-nav navbar-right"> <li><a href="{% url 'login' %}">Log in</a></li> </ul> {% endif %}appภายในโฟลเดอร์ สร้างไฟล์forms.pyด้วยเนื้อหาด้านล่างfrom django import forms from django.contrib.auth.forms import AuthenticationForm from django.utils.translation import ugettext_lazy as _ class BootstrapAuthenticationForm(AuthenticationForm): """Authentication form which uses boostrap CSS.""" username = forms.CharField(max_length=254, widget=forms.TextInput({ 'class': 'form-control', 'placeholder': 'User name'})) password = forms.CharField(label=_("Password"), widget=forms.PasswordInput({ 'class': 'form-control', 'placeholder':'Password'}))ปรับเปลี่ยน
app/models.pyให้ตรงกับโค้ดต่อไปนี้from django.db import models from django.contrib.auth.models import User # In this web app a Microsoft Advertising user maps a Django web user to a refresh token. class BingAdsUser(models.Model): user = models.OneToOneField(User, on_delete=models.PROTECT) refresh_token = models.CharField(max_length=200) # def __unicode__(self): # __unicode__ on Python 2 # return self.refresh_token def __str__(self): # __str__ on Python 3 return self.refresh_tokenปรับเปลี่ยน
app/views.pyให้ตรงกับโค้ดต่อไปนี้from django.http import HttpRequest, HttpResponse from django.shortcuts import render from django.template.loader import get_template, render_to_string from web_project import settings from datetime import datetime from django.shortcuts import redirect from django.contrib.auth import authenticate, login, logout, get_user_model from django.contrib.auth.models import User from app.models import BingAdsUser from bingads import * # import logging # logging.basicConfig(level=logging.INFO) # logging.getLogger('suds.client').setLevel(logging.DEBUG) # logging.getLogger('suds.transport').setLevel(logging.DEBUG) authorization_data = AuthorizationData( account_id=None, customer_id=None, developer_token=None, authentication=None) customer_service=None def home(request): """ If an authenticated user returns to this page after logging in, the appropriate context is provided to index.html for rendering the page. """ assert isinstance(request, HttpRequest) # If the Django user has a refresh token stored, # try to use it to get Microsoft Advertising data. if user_has_refresh_token(request.user.username): return redirect('/callback') else: return render( request, 'app/index.html' ) def callback(request): """Handles OAuth authorization, either via callback or direct refresh request.""" assert isinstance(request, HttpRequest) authentication = OAuthWebAuthCodeGrant( client_id=settings.CLIENT_ID, client_secret=settings.CLIENT_SECRET, redirection_uri=settings.REDIRECTION_URI, env=settings.ENVIRONMENT) return authorize_bing_ads_user(request, authentication) def authorize_bing_ads_user(request, authentication): assert isinstance(request, HttpRequest) global customer_service bingadsuser = None try: Users = get_user_model() user = User.objects.get(username=request.user.username) except User.DoesNotExist: return render( request, 'app/index.html' ) try: bingadsuser = user.bingadsuser except BingAdsUser.DoesNotExist: bingadsuser = BingAdsUser() bingadsuser.user = user pass try: # If we have a refresh token let's refresh the access token. if(bingadsuser is not None and bingadsuser.refresh_token != ""): authentication.request_oauth_tokens_by_refresh_token(bingadsuser.refresh_token) bingadsuser.refresh_token = authentication.oauth_tokens.refresh_token # If the current HTTP request is a callback from the Microsoft Account authorization server, # use the current request url containing authorization code to request new access and refresh tokens. elif (request.GET.get('code') is not None): authentication.request_oauth_tokens_by_response_uri(response_uri = request.get_full_path()) bingadsuser.refresh_token = authentication.oauth_tokens.refresh_token except OAuthTokenRequestException: bingadsuser.refresh_token = "" user.save() bingadsuser.save() # If there is no refresh token saved and no callback from the authorization server, # then connect to the authorization server and request user consent. if (bingadsuser.refresh_token == ""): return redirect(authentication.get_authorization_endpoint()) set_session_data(request, authentication) # At this point even if the user has valid Django web application credentials, # we don't know whether they have access to Microsoft Advertising. # Let's test to see if they can call Bing Ads API service operations. bing_ads_user = None accounts=[] errors=[] try: bing_ads_user = get_user(None) accounts = search_accounts_by_user_id(bing_ads_user.Id)['AdvertiserAccount'] except WebFault as ex: errors=get_webfault_errors(ex) pass context = { 'bingadsuser': bing_ads_user, 'accounts': accounts, 'errors': errors, } return render( request, 'app/index.html', context ) def revoke(request): """Deletes the refresh token for the user authenticated in the current session.""" assert isinstance(request, HttpRequest) try: Users = get_user_model() user = User.objects.get(username=request.user.username) bingadsuser = user.bingadsuser if(bingadsuser is not None): bingadsuser.refresh_token = "" bingadsuser.save() except User.DoesNotExist: pass except BingAdsUser.DoesNotExist: pass clear_session_data(request) return render( request, 'app/index.html' ) def user_has_active_session(request): try: return True if request.session['is_authenticated'] else False except KeyError: return False def user_has_refresh_token(username): try: Users = get_user_model() user = User.objects.get(username=username) bingadsuser = user.bingadsuser if(bingadsuser is not None and bingadsuser.refresh_token != ""): return True except User.DoesNotExist: return False except BingAdsUser.DoesNotExist: return False def set_session_data(request, authentication): global authorization_data global customer_service try: request.session['is_authenticated'] = True authorization_data.authentication = authentication authorization_data.developer_token = settings.DEVELOPER_TOKEN customer_service = ServiceClient( service='CustomerManagementService', version=settings.API_VERSION, authorization_data=authorization_data, environment=settings.ENVIRONMENT ) except KeyError: pass return None def clear_session_data(request): global authorization_data global customer_service request.session['is_authenticated'] = False authorization_data = AuthorizationData(account_id=None, customer_id=None, developer_token=None, authentication=None) customer_service = None def applogout(request): logout(request) clear_session_data(request) return redirect('/') def get_user(user_id): ''' Gets a Microsoft Advertising User object by the specified user ID. :param user_id: The Microsoft Advertising user identifier. :type user_id: long :return: The Microsoft Advertising user. :rtype: User ''' global customer_service return customer_service.GetUser(UserId = user_id).User def search_accounts_by_user_id(user_id): ''' Search for account details by UserId. :param user_id: The Microsoft Advertising user identifier. :type user_id: long :return: List of accounts that the user can manage. :rtype: Dictionary of AdvertiserAccount ''' predicates={ 'Predicate': [ { 'Field': 'UserId', 'Operator': 'Equals', 'Value': user_id, }, ] } accounts=[] page_index = 0 PAGE_SIZE=100 found_last_page = False while (not found_last_page): paging=set_elements_to_none(customer_service.factory.create('ns5:Paging')) paging.Index=page_index paging.Size=PAGE_SIZE search_accounts_response = customer_service.SearchAccounts( PageInfo=paging, Predicates=predicates ) if search_accounts_response is not None and hasattr(search_accounts_response, 'AdvertiserAccount'): accounts.extend(search_accounts_response['AdvertiserAccount']) found_last_page = PAGE_SIZE > len(search_accounts_response['AdvertiserAccount']) page_index += 1 else: found_last_page=True return { 'AdvertiserAccount': accounts } def set_elements_to_none(suds_object): for (element) in suds_object: suds_object.__setitem__(element[0], None) return suds_object def get_webfault_errors(ex): errors=[] if not hasattr(ex.fault, "detail"): raise Exception("Unknown WebFault") error_attribute_sets = ( ["ApiFault", "OperationErrors", "OperationError"], ["AdApiFaultDetail", "Errors", "AdApiError"], ["ApiFaultDetail", "BatchErrors", "BatchError"], ["ApiFaultDetail", "OperationErrors", "OperationError"], ["EditorialApiFaultDetail", "BatchErrors", "BatchError"], ["EditorialApiFaultDetail", "EditorialErrors", "EditorialError"], ["EditorialApiFaultDetail", "OperationErrors", "OperationError"], ) for error_attribute_set in error_attribute_sets: errors = get_api_errors(ex.fault.detail, error_attribute_set) if errors is not None: return errors return None def get_api_errors(error_detail, error_attribute_set): api_errors = error_detail for field in error_attribute_set: api_errors = getattr(api_errors, field, None) if api_errors is None: return None errors=[] if type(api_errors) == list: for api_error in api_errors: errors.append(api_error) else: errors.append(api_errors) return errorsแทนที่เนื้อหาของ
web_project/urls.pyด้วยเนื้อหาด้านล่าง ไฟล์urls.pyคือที่ที่คุณระบุรูปแบบเพื่อกําหนดเส้นทาง URL ที่แตกต่างกันไปยังมุมมองที่เหมาะสม ตัวอย่างเช่น โค้ดด้านล่างจะแมป URL รากของแอป ("") ไปยังhomeฟังก์ชันที่คุณเพิ่งเพิ่มไปยังapp/views.py:from django.contrib import admin from django.urls import path from app import views as app_views from django.contrib.auth import views as auth_views from datetime import datetime from django.conf.urls import include, url from app.forms import BootstrapAuthenticationForm from django.contrib.auth.views import HttpResponseRedirect from django.contrib import admin admin.autodiscover() urlpatterns = [ url(r'^applogout', app_views.applogout, name='applogout'), url(r'^callback', app_views.callback, name='callback'), url(r'^revoke', app_views.revoke, name='revoke'), url(r'^$', app_views.home, name='home'), url(r'^login/$', auth_views.LoginView.as_view( template_name='app/login.html', authentication_form=BootstrapAuthenticationForm, extra_context= { 'title':'Log in', 'year':datetime.now().year, } ), name='login'), url(r'^logout$', auth_views.LogoutView.as_view(), { 'next_page': '/', }, name='logout'), url(r'^admin/', admin.site.urls), ]บันทึกไฟล์ที่ปรับเปลี่ยนทั้งหมดด้วย
Ctrl+K Sเรียกใช้
python manage.py makemigrationsเพื่อสร้างสคริปต์ในโฟลเดอร์การโยกย้ายที่โยกย้ายฐานข้อมูลจากสถานะปัจจุบันไปยังสถานะใหม่เรียกใช้
python manage.py migrateเพื่อนําสคริปต์ไปใช้กับฐานข้อมูลจริง สคริปต์การโยกย้ายจะบันทึกการเปลี่ยนแปลงแบบเพิ่มหน่วยทั้งหมดที่คุณทํากับแบบจําลองข้อมูลของคุณ (models.py) อย่างมีประสิทธิภาพเมื่อเวลาผ่านไป ด้วยการใช้การโยกย้าย Django จะอัปเดตฐานข้อมูลให้ตรงกับแบบจําลองของคุณ เนื่องจากการเปลี่ยนแปลงแบบเพิ่มหน่วยแต่ละรายการมีสคริปต์ของตนเอง Django จึงสามารถโยกย้ายฐานข้อมูลเวอร์ชันก่อนหน้าใดๆ (รวมถึงฐานข้อมูลใหม่) ไปยังเวอร์ชันปัจจุบันได้โดยอัตโนมัติ ด้วยเหตุนี้ คุณจําเป็นต้องกังวลเกี่ยวกับแบบจําลองของคุณใน models.py เท่านั้น โดยไม่ต้องมี Schema ฐานข้อมูลพื้นฐานหรือสคริปต์การโยกย้าย คุณปล่อยให้ Django ทําส่วนนั้น!สร้างบัญชีผู้ใช้ขั้นสูงในแอปโดยการเปิด Terminal ใน VS Code สําหรับสภาพแวดล้อมเสมือนจากนั้นเรียกใช้คําสั่ง
python manage.py createsuperuser --username=<username> --email=<email>แทนที่<username>และ<email>ด้วยข้อมูลส่วนบุคคลของคุณ เมื่อคุณเรียกใช้คําสั่ง Django จะพร้อมท์ให้คุณป้อนและยืนยันรหัสผ่านของคุณสิ่งสำคัญ
อย่าลืมใส่ชื่อผู้ใช้และรหัสผ่านของคุณ นี่คือข้อมูลประจําตัวที่คุณใช้เพื่อรับรองความถูกต้องในพอร์ทัลผู้ดูแลระบบของเว็บแอป
ใน VS Code Terminal อีกครั้งเมื่อเปิดใช้งานสภาพแวดล้อมเสมือนให้เรียกใช้เซิร์ฟเวอร์การพัฒนาด้วย
python manage.py runserverและเปิดเบราว์เซอร์http://127.0.0.1:8000/เพื่อดูหน้าที่แสดงผล "Hello, Django"ในเว็บเบราว์เซอร์ ให้ไปที่
http://127.0.0.1:8000/admin/และสร้างผู้ใช้เว็บ Django ใหม่ภายใต้ ผู้ใช้ ซึ่งจะแตกต่างจากข้อมูลประจําตัวผู้ใช้ Microsoft Advertising ของคุณ เพื่อให้ผู้ใช้ Microsoft Advertising หลายรายสามารถเข้าสู่ระบบแอปของคุณแยกต่างหากได้
เข้าสู่ระบบด้วยผู้ใช้ใหม่ (ไม่ใช่ผู้ดูแลระบบขั้นสูง) และคุณควรเห็นตัวเลือกในการรับรองความถูกต้องกับบัญชี Microsoft
หลังจากที่คุณคลิก รับรองความถูกต้องของบัญชี Microsoft คุณจะได้รับแจ้งให้มอบสิทธิ์เว็บแอปของคุณเองเพื่อจัดการบัญชี Microsoft Advertising ของคุณ ถ้าคุณยินยอม และถ้าคุณมีสิทธิ์เข้าถึงบัญชี Microsoft Advertising คุณควรเปลี่ยนเส้นทางไปยังมุมมองของชื่อบัญชีของคุณและ ID