Exemplarische Vorgehensweise: Bing Ads-API-Webanwendung in Python
In diesem Tutorial erfahren Sie, wie Sie mit der Ausführung einer Microsoft Advertising-Webanwendung mit dem Bing Ads Python SDK, der Visual Studio Code-IDE und dem Django-Webframework beginnen.
In diesem Tutorial werden verschiedene Details zu Django selbst nicht untersucht, z. B. das Arbeiten mit Datenmodellen und das Erstellen einer Verwaltungsschnittstelle. Anleitungen zu diesen Aspekten finden Sie in der Django-Dokumentation. Weitere Informationen zum Arbeiten mit Django im VS Code-Terminal, Editor und Debugger finden Sie unter Verwenden von Django in Visual Studio Code. Dieses Tutorial basiert stark auf den Setupanweisungen unter Verwenden von Django in Visual Studio Code.
Übersicht über Beispielwebanwendungen
Am Ende dieses Tutorials wird eine Webanwendung ausgeführt, die Ihre http://localhost Microsoft Advertising-Benutzeranmeldeinformationen authentifiziert und Ihre Benutzer- und Kontoinformationen anzeigt. Anschließend können Sie mehrere Webanwendungsbenutzer hinzufügen, die den Zugriff für Ihre Anwendung aktivieren können, um ihre Microsoft Advertising-Anmeldeinformationen zu verwenden. Diese Webanwendung stellt eine 1:1-Zuordnung eines Webanwendungsbenutzers bereit, z. B. ContosoUser zu einem Microsoft Advertising-Benutzer. Weitere Informationen zum Ändern des Datenmodells finden Sie in der Django-Dokumentation . Wenn Ihr Webanwendungsbenutzer den Zugriff auf seine Microsoft Advertising-Konten mit einem Microsoft-Konto ermöglicht, wird ein Aktualisierungstoken in der SQL Lite-Datenbank auf Ihrem Webserver gespeichert.
Voraussetzungen
Sie müssen Visual Studio Code installiert haben, um dieses Tutorial ausführen zu können. Zum Ausführen der Django-Web-App können Sie Visual Studio Community oder Visual Studio Professional verwenden. Die Setupschritte unterscheiden sich jedoch von den Schritten in diesem Tutorial.
Python 3 muss über python.org installiert sein. verwenden Sie in der Regel die Schaltfläche Python 3.7.0 herunterladen , die zuerst auf der Seite angezeigt wird (oder was auch immer die neueste Version ist). Stellen Sie unter Windows sicher, dass der Speicherort Ihres Python-Interpreters in Ihrer PATH-Umgebungsvariablen enthalten ist. Sie können dies überprüfen, indem Sie an der Eingabeaufforderung ausführen path
. Wenn der Ordner des Python-Interpreters nicht enthalten ist, öffnen Sie Windows-Einstellungen, suchen Sie nach "Umgebung", wählen Sie Umgebungsvariablen für Ihr Konto bearbeiten aus, und bearbeiten Sie dann die Variable Path , um diesen Ordner einzuschließen.
Sie müssen das Bing Ads Python SDKinstallieren, und dieses Tutorial führt Sie durch die Installation.
Sie müssen das Django-Webframework installiert haben, um die Anwendung lokal bereitzustellen. In diesem Tutorial wird die Installation erläutert.
Sie benötigen mindestens einen Benutzer mit Microsoft Advertising-Anmeldeinformationen und ein Entwicklertoken.
Sie müssen eine Anwendung registrieren und sich die Client-ID (registrierte Anwendungs-ID) und den geheimen Clientschlüssel (registriertes Kennwort) notieren. Für dieses Beispiel müssen Sie eine Web-App (nicht nativ) registrieren. Sie werden aufgefordert, eine oder mehrere Umleitungs-URLs zu registrieren. Für dieses Tutorial sollten Sie registrieren http://localhost/callback. Sie sollten stattdessen https verwenden, wenn Sie auf einem Produktionsserver bereitgestellt werden. Weitere Informationen zum Registrieren einer Anwendung und zum Autorisierungscodegenehmigungsflow finden Sie unter Authentifizierung mit OAuth.
Dieses Tutorial wurde unter Windows entwickelt. Obwohl Windows zum Ausführen des Beispiels nicht erforderlich ist, unterscheiden sich einige der folgenden Schritte, wenn Sie ein anderes Betriebssystem verwenden, z. B. Linux oder MacOS.
Erstellen einer Projektumgebung für Django
In diesem Abschnitt erstellen Sie eine virtuelle Umgebung, in der Django installiert ist. Die Verwendung einer virtuellen Umgebung vermeidet die Installation von Django in einer globalen Python-Umgebung und bietet Ihnen die genaue Kontrolle über die in einer Anwendung verwendeten Bibliotheken.
Erstellen Sie in Ihrem Dateisystem einen Projektordner für dieses Tutorial, z
hello_django
. B. .Öffnen Sie im
hello_django
Ordner PowerShell oder Ihre bevorzugte Skriptshell, und verwenden Sie den folgenden Befehl, um eine virtuelle Umgebung namensenv
basierend auf Ihrem aktuellen Interpreter zu erstellen:py -3 -m venv env
Öffnen Sie den
hello_django
Projektordner in VS Code, indem Siecode .
ausführen oder VS Code ausführen und den Befehl Dateiordner>öffnen verwenden.Öffnen Sie in VS Code die Befehlspalette (Befehlspalette anzeigen> oder
Ctrl+Shift+P
). Wählen Sie dann den Befehl Python: Interpreter auswählen aus.Der Befehl zeigt eine Liste der verfügbaren Interpreter an, die VS Code automatisch finden kann. Ihre Liste variiert; Wenn der gewünschte Interpreter nicht angezeigt wird, finden Sie weitere Informationen unter Konfigurieren von Python-Umgebungen. Wählen Sie in der Liste die virtuelle Umgebung in Ihrem Projektordner aus, die mit
./env
oder.\env
beginnt:Terminal ausführen: Neues Terminal (
Ctrl+Shift+ `
) aus der Befehlspalette, das ein Terminal erstellt und die virtuelle Umgebung automatisch durch Ausführen des Aktivierungsskripts aktiviert.Hinweis
Wenn der Standardterminaltyp unter Windows PowerShell ist, wird möglicherweise ein Fehler angezeigt, dass es nicht activate.ps1 ausgeführt werden kann, da die Ausführung von Skripts auf dem System deaktiviert ist. Der Fehler sollte einen Link mit Informationen zum Zulassen von Skripts enthalten. Verwenden Sie andernfalls Terminal: Wählen Sie Standardshell aus , um Ihre bevorzugte Standardeinstellung festzulegen.
Die ausgewählte Umgebung wird in der unteren linken Ecke der vs Code-status angezeigt. Beachten Sie den Indikator (venv), der Ihnen mitteilt, dass Sie eine virtuelle Umgebung verwenden:
Installieren Sie Django in der virtuellen Umgebung über pip im VS Code-Terminal:
python -m pip install django
Installieren Sie das Bing Ads Python SDK in der virtuellen Umgebung über pip im VS Code-Terminal:
python -m pip install bingads
Sie verfügen jetzt über eine eigenständige virtuelle Umgebung, die zum Schreiben von Django- und Microsoft Advertising-Code bereit ist.
Erstellen und Ausführen einer Django-App
In der Django-Terminologie besteht ein "Django-Projekt" aus mehreren Konfigurationsdateien auf Websiteebene sowie einer oder mehreren "Apps", die Sie auf einem Webhost bereitstellen, um eine vollständige Webanwendung zu erstellen. Ein Django-Projekt kann mehrere Apps enthalten, von denen jede in der Regel eine unabhängige Funktion im Projekt hat, und dieselbe App kann sich in mehreren Django-Projekten befinden. Eine App ist ihrerseits nur ein Python-Paket, das bestimmte Konventionen befolgt, die Django erwartet.
Um eine Django-App zu erstellen, müssen Sie zunächst das Django-Projekt erstellen, das als Container für die App dient, und dann die App selbst erstellen. Für beide Zwecke verwenden Sie das Verwaltungshilfsprogramm Django , django-admin
das bei der Installation des Django-Pakets installiert wird.
Erstellen des Django-Projekts
Führen Sie im VS Code-Terminal, in dem Ihre virtuelle Umgebung aktiviert ist, den folgenden Befehl aus:
django-admin startproject web_project .
Dieser
startproject
Befehl geht davon aus (mit am.
Ende), dass der aktuelle Ordner Ihr Projektordner ist, und erstellt Folgendes darin:manage.py
: Das Django-Befehlszeilen-Verwaltungshilfsprogramm für das Projekt. Sie führen administrative Befehle für das Projekt mit auspython manage.py <command> [options]
.Ein Unterordner mit dem Namen
web_project
, der die folgenden Dateien enthält:-
__init__.py
: Eine leere Datei, die Python mitteilt, dass dieser Ordner ein Python-Paket ist. -
wsgi.py
: Ein Einstiegspunkt für WSGI-kompatible Webserver zur Bereitstellung Ihres Projekts. Sie lassen diese Datei in der Regel unverändert, da sie die Hooks für Produktionswebserver bereitstellt. -
settings.py
: Enthält Einstellungen für das Django-Projekt, die Sie im Rahmen der Entwicklung einer Web-App ändern. -
urls.py
: enthält ein Inhaltsverzeichnis für das Django-Projekt, das Sie auch im Laufe der Entwicklung ändern.
-
Um das Django-Projekt zu überprüfen, stellen Sie sicher, dass Ihre virtuelle Umgebung aktiviert ist, und starten Sie dann den Entwicklungsserver von Django mit dem Befehl
python manage.py runserver
. Der Server wird am Standardport 8000 ausgeführt, und im Ausgabefenster des VS Code-Terminals wird eine Ausgabe wie die folgende angezeigt: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.
Wenn Sie den Server zum ersten Mal ausführen, wird eine SQLite-Standarddatenbank in der Datei
db.sqlite3
erstellt, die in der Regel für Entwicklungszwecke vorgesehen ist, aber in der Produktion für Web-Apps mit geringem Volumen verwendet werden kann. Außerdem ist der integrierte Webserver von Django nur für lokale Entwicklungszwecke vorgesehen. Wenn Sie jedoch auf einem Webhost bereitstellen, verwendet Django stattdessen den Webserver des Hosts. Daswsgi.py
Modul im Django-Projekt übernimmt die Anbindung an die Produktionsserver.Wenn Sie einen anderen Port als den Standardport 8000 verwenden möchten, geben Sie einfach die Portnummer in der Befehlszeile an, z
python manage.py runserver 5000
. B. .Ctrl+click
diehttp://127.0.0.1:8000/
URL im Ausgabefenster des VS Code-Terminals, um Ihren Standardbrowser mit dieser Adresse zu öffnen. Wenn Django ordnungsgemäß installiert ist und das Projekt gültig ist, wird unten die Standardseite angezeigt. Im Fenster Ausgabe von VS Code wird auch das Serverprotokoll angezeigt.Wenn Sie fertig sind, schließen Sie das Browserfenster, und beenden Sie den Server in VS Code mithilfe von
Ctrl+C
, wie im Ausgabefenster des VS Code-Terminals angegeben.
Erstellen einer Django-App für Microsoft Advertising
Führen Sie im VS Code-Terminal mit aktivierter virtueller Umgebung den Befehl des
startapp
Verwaltungshilfsprogramms in Ihrem Projektordner (in demmanage.py
sich befindet) aus:python manage.py startapp app
Der Befehl erstellt einen Ordner namens
app
, der eine Reihe von Codedateien und einen Unterordner enthält. Von diesen arbeiten Sie häufig mitviews.py
(die Funktionen enthält, die Seiten in Ihrer Web-App definieren) undmodels.py
(die Klassen enthält, die Ihre Datenobjekte definieren). Dermigrations
Ordner wird vom Verwaltungshilfsprogramm von Django zum Verwalten von Datenbankversionen verwendet, wie weiter unten in diesem Tutorial erläutert. Es gibt auch die Dateienapps.py
(App-Konfiguration),admin.py
(zum Erstellen einer Verwaltungsschnittstelle) undtests.py
(für Komponententests), die hier nicht behandelt werden.Fügen Sie in
app/settings.py
den folgenden Code hinzu, und legen Sie Ihre eigenen werte für CLIENT_ID, CLIENT_SECRET, DEVELOPER_TOKEN und ENVIRONMENT fest .""" 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
Fügen Sie in
app/settings.py
der Liste der installierten Apps hinzuapp
.INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app', ]
Erstellen Sie im VS Code-Terminal die
app/static/app
Ordner undapp/templates/app
:(env) PS C:\dev\hello_django> mkdir app/static/app (env) PS C:\dev\hello_django> mkdir app/templates/app
Erstellen Sie in den
app/static/app
Ordnern eine neue Datei namens site.css , und fügen Sie den folgenden Inhalt hinzu..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%; }
Erstellen Sie innerhalb des
app/templates/app
Ordners eine Dateiindex.html
mit dem folgenden Inhalt.{% 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 %}
Erstellen Sie innerhalb des
app/templates/app
Ordners eine Dateilayout.html
mit dem folgenden Inhalt.<!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>
Erstellen Sie innerhalb des
app/templates/app
Ordners eine Dateilogin.html
mit dem folgenden Inhalt.{% 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 %}
Erstellen Sie innerhalb des
app/templates/app
Ordners eine Dateiloginpartial.html
mit dem folgenden Inhalt.{% 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 %}
Erstellen Sie innerhalb des
app
Ordners eine Dateiforms.py
mit dem folgenden Inhalt.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'}))
Ändern Sie
app/models.py
, um dem folgenden Code zu entsprechen.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
Ändern Sie
app/views.py
, um dem folgenden Code zu entsprechen.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
Ersetzen Sie den Inhalt von
web_project/urls.py
durch den folgenden Inhalt. Inurls.py
der Datei geben Sie Muster an, um verschiedene URLs an die entsprechenden Ansichten weiterzuleiten. Der folgende Code ordnet beispielsweise die Stamm-URL der App (""
) derhome
Funktion zu, die Sie gerade hinzugefügt habenapp/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), ]
Speichern Sie alle geänderten Dateien mit
Ctrl+K S
.Führen Sie aus
python manage.py makemigrations
, um Skripts im Migrationsordner zu generieren, die die Datenbank vom aktuellen Zustand in den neuen Zustand migrieren.Führen Sie aus
python manage.py migrate
, um die Skripts auf die eigentliche Datenbank anzuwenden. Die Migrationsskripts zeichnen effektiv alle inkrementellen Änderungen auf, die Sie im Laufe der Zeit an Ihren Datenmodellen (models.py
) vornehmen. Durch Anwenden der Migrationen aktualisiert Django die Datenbank entsprechend Ihren Modellen. Da jede inkrementelle Änderung über ein eigenes Skript verfügt, kann Django automatisch jede frühere Version einer Datenbank (einschließlich einer neuen Datenbank) zur aktuellen Version migrieren. Daher müssen Sie sich nur mit Ihren Modellen in models.py befassen, niemals mit dem zugrunde liegenden Datenbankschema oder den Migrationsskripts. Sie lassen Django diesen Teil erledigen!Erstellen Sie ein Superuser-Konto in der App, indem Sie ein Terminal in VS Code für Ihre virtuelle Umgebung öffnen und dann den Befehl
python manage.py createsuperuser --username=<username> --email=<email>
ausführen, und<username>
ersetzen Sie und<email>
natürlich durch Ihre persönlichen Informationen. Wenn Sie den Befehl ausführen, fordert Django Sie auf, Ihr Kennwort einzugeben und zu bestätigen.Wichtig
Achten Sie darauf, dass Sie sich Ihre Kombination aus Benutzername und Kennwort merken. Dies sind die Anmeldeinformationen, die Sie für die Authentifizierung im Verwaltungsportal der Web-App verwenden.
Führen Sie im VS Code-Terminal mit aktivierter virtueller Umgebung den Entwicklungsserver mit
python manage.py runserver
aus, und öffnen Sie einen Browser, um eine Seite anzuzeigenhttp://127.0.0.1:8000/
, auf der "Hello, Django" gerendert wird.Wechseln Sie im Webbrowser zu
http://127.0.0.1:8000/admin/
, und erstellen Sie unter Benutzer einen neuen Django-Webbenutzer. Dies unterscheidet sich von Ihren Microsoft Advertising-Benutzeranmeldeinformationen, sodass sich mehrere Microsoft Advertising-Benutzer separat bei Ihrer App anmelden können.Melden Sie sich mit dem neuen Benutzer (nicht mit dem Superadministrator) an. Daraufhin sollte die Option zur Authentifizierung mit einem Microsoft-Konto angezeigt werden.
Nachdem Sie auf Microsoft-Konto authentifizieren geklickt haben, werden Sie aufgefordert, Ihren eigenen Web-App-Berechtigungen zum Verwalten Ihrer Microsoft Advertising-Konten zu erteilen. Wenn Sie zustimmen und Zugriff auf Microsoft Advertising-Konten haben, sollten Sie zu einer Ansicht Ihrer Kontonamen und IDs weitergeleitet werden.
Siehe auch
Erste Schritte bei der Verwendung von Python mit der Bing Ads-API