Procedura dettagliata: Applicazione Web dell'API Bing Ads in Python
Questa esercitazione illustra come iniziare a eseguire un'applicazione Web Microsoft Advertising usando Bing Ads Python SDK, l'IDE di Visual Studio Code e il framework Web Django .
Questa esercitazione non esplora vari dettagli su Django stesso, ad esempio l'uso di modelli di dati e la creazione di un'interfaccia amministrativa. Per indicazioni su questi aspetti, vedere la documentazione di Django. Per altre informazioni su come usare Django nel terminale, nell'editor e nel debugger di VS Code, vedere Usare Django in Visual Studio Code. Questa esercitazione prende in prestito molto dalle istruzioni di configurazione in Usare Django in Visual Studio Code.
Panoramica dell'applicazione Web di esempio
Al termine di questa esercitazione si avrà un'applicazione Web in esecuzione su http://localhost che autentica le credenziali utente di Microsoft Advertising e visualizza le informazioni sull'utente e sugli account. È quindi possibile aggiungere più utenti dell'applicazione Web, che possono abilitare l'accesso per l'applicazione per l'uso delle credenziali di Microsoft Advertising. Questa applicazione Web fornisce un mapping uno a uno di un utente di un'applicazione Web, ad esempio ContosoUser a un utente di Microsoft Advertising. Per informazioni su come modificare il modello di dati, vedere la documentazione di Django per altre informazioni. Se l'utente dell'applicazione Web consente l'accesso ai propri account Microsoft Advertising con un account Microsoft, un token di aggiornamento viene archiviato nel database SQL Lite nel server Web.
Prerequisiti
Per seguire questa esercitazione, è necessario che Visual Studio Code sia installato. Per eseguire l'app Web Django, è possibile usare Visual Studio Community o Visual Studio Professional. Tuttavia, i passaggi di installazione variano da quelli di questa esercitazione.
Sarà necessario che Python 3 sia installato da python.org; in genere usare il pulsante Scarica Python 3.7.0 visualizzato per primo nella pagina (o qualsiasi altra versione più recente). In Windows verificare che il percorso dell'interprete Python sia incluso nella variabile di ambiente PATH. È possibile verificarlo eseguendo path
al prompt dei comandi. Se la cartella dell'interprete Python non è inclusa, aprire Impostazioni di Windows, cercare "ambiente", selezionare Modifica variabili di ambiente per l'account e quindi modificare la variabile Path per includere tale cartella.
Sarà necessario installareBing Ads Python SDK e questa esercitazione illustra l'installazione.
Per distribuire l'applicazione in locale è necessario il framework Web Django e questa esercitazione illustra l'installazione.
Sarà necessario almeno un utente con le credenziali di Microsoft Advertising e un token per sviluppatori.
Sarà necessario registrare un'applicazione e prendere nota dell'ID client (ID applicazione registrato) e del segreto client (password registrata). Sarà necessario registrare un'app Web (non nativa) per questo esempio. Verrà richiesto di registrare uno o più URL di reindirizzamento e per questa esercitazione è necessario registrare http://localhost/callback. È invece consigliabile usare https quando viene distribuito in un server di produzione. Per altre informazioni sulla registrazione di un'applicazione e sul flusso di concessione del codice di autorizzazione, vedere Autenticazione con OAuth.
Questa esercitazione è stata sviluppata in Windows. Anche se Windows non è necessario per eseguire l'esempio, alcuni dei passaggi seguenti variano se si usa un altro sistema operativo, ad esempio Linux o MacOS.
Creare un ambiente di progetto per Django
In questa sezione viene creato un ambiente virtuale in cui è installato Django. L'uso di un ambiente virtuale evita di installare Django in un ambiente Python globale e offre il controllo esatto sulle librerie usate in un'applicazione.
Nel file system creare una cartella di progetto per questa esercitazione, ad
hello_django
esempio .hello_django
Nella cartella aprire PowerShell o la shell degli script preferiti e usare il comando seguente per creare un ambiente virtuale denominatoenv
in base all'interprete corrente:py -3 -m venv env
Aprire la cartella del
hello_django
progetto in VS Code eseguendocode .
o eseguendo VS Code e usando il comandoApri cartellafile>.In VS Code aprire il riquadro comandi (Riquadro comandivisualizza> o
Ctrl+Shift+P
). Selezionare quindi il comando Python: Select Interpreter (Python: Seleziona interprete ).Il comando presenta un elenco di interpreti disponibili che VS Code può individuare automaticamente. L'elenco varia; se l'interprete desiderato non è visualizzato, vedere Configurazione degli ambienti Python. Nell'elenco selezionare l'ambiente virtuale nella cartella del progetto che inizia con
./env
o.\env
:Esegui terminale: nuovo terminale (
Ctrl+Shift+ `
) dal riquadro comandi, che crea un terminale e attiva automaticamente l'ambiente virtuale eseguendo il relativo script di attivazione.Nota
In Windows, se il tipo di terminale predefinito è PowerShell, potrebbe essere visualizzato un errore che indica che non è possibile eseguire activate.ps1 perché l'esecuzione di script è disabilitata nel sistema. L'errore deve fornire un collegamento per informazioni su come consentire gli script. In caso contrario, usare Terminale: selezionare Shell predefinita per impostare il valore predefinito preferito.
L'ambiente selezionato viene visualizzato nell'angolo inferiore sinistro della barra di stato di VS Code. Si noti l'indicatore (venv) che indica che si sta usando un ambiente virtuale:
Installare Django nell'ambiente virtuale tramite pip nel terminale di VS Code:
python -m pip install django
Installare Bing Ads Python SDK nell'ambiente virtuale tramite pip nel terminale di VS Code:
python -m pip install bingads
È ora disponibile un ambiente virtuale autonomo pronto per la scrittura di codice Django e Microsoft Advertising.
Creare ed eseguire un'app Django
Nella terminologia django, un "progetto Django" è costituito da diversi file di configurazione a livello di sito insieme a una o più "app" distribuite in un host Web per creare un'applicazione Web completa. Un progetto Django può contenere più app, ognuna delle quali ha in genere una funzione indipendente nel progetto e la stessa app può trovarsi in più progetti Django. Un'app, da parte sua, è solo un pacchetto Python che segue determinate convenzioni che Django prevede.
Per creare un'app Django, è quindi necessario prima creare il progetto Django per fungere da contenitore per l'app, quindi creare l'app stessa. Per entrambi gli scopi si usa l'utilità amministrativa Django, , django-admin
che viene installata quando si installa il pacchetto Django.
Creare il progetto Django
Nel terminale di VS Code in cui è attivato l'ambiente virtuale eseguire il comando seguente:
django-admin startproject web_project .
Questo
startproject
comando presuppone (tramite l'uso di.
alla fine) che la cartella corrente sia la cartella del progetto e crea quanto segue al suo interno:manage.py
: utilità amministrativa della riga di comando Django per il progetto. È possibile eseguire comandi amministrativi per il progetto usandopython manage.py <command> [options]
.Sottocartella denominata
web_project
, che contiene i file seguenti:-
__init__.py
: file vuoto che indica a Python che questa cartella è un pacchetto Python. -
wsgi.py
: punto di ingresso per i server Web compatibili con WSGI per gestire il progetto. Questo file viene in genere lasciato così come è perché fornisce gli hook per i server Web di produzione. -
settings.py
: contiene le impostazioni per il progetto Django, che vengono modificate durante lo sviluppo di un'app Web. -
urls.py
: contiene un sommario per il progetto Django, che viene modificato anche nel corso dello sviluppo.
-
Per verificare il progetto Django, verificare che l'ambiente virtuale sia attivato, quindi avviare il server di sviluppo di Django usando il comando
python manage.py runserver
. Il server viene eseguito sulla porta predefinita 8000 e viene visualizzato un output simile al seguente nella finestra di output del terminale di 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.
Quando si esegue il server la prima volta, viene creato un database SQLite predefinito nel file
db.sqlite3
, che in genere è destinato allo sviluppo, ma può essere usato in produzione per le app Web a basso volume. Inoltre, il server Web predefinito di Django è destinato solo a scopi di sviluppo locale. Quando si esegue la distribuzione in un host Web, tuttavia, Django usa invece il server Web dell'host. Ilwsgi.py
modulo nel progetto Django si occupa dell'associazione ai server di produzione.Se si vuole usare una porta diversa da quella predefinita 8000, è sufficiente specificare il numero di porta nella riga di comando, ad
python manage.py runserver 5000
esempio .Ctrl+click
l'URLhttp://127.0.0.1:8000/
nella finestra di output del terminale vs Code per aprire il browser predefinito a tale indirizzo. Se Django è installato correttamente e il progetto è valido, viene visualizzata la pagina predefinita visualizzata di seguito. La finestra Output di VS Code mostra anche il log del server.Al termine, chiudere la finestra del browser e arrestare il server in VS Code usando
Ctrl+C
come indicato nella finestra di output del terminale di VS Code.
Creare un'app Django per Microsoft Advertising
Nel terminale di VS Code con l'ambiente virtuale attivato eseguire il comando dell'utilità amministrativa nella cartella del
startapp
progetto (dovemanage.py
si trova):python manage.py startapp app
Il comando crea una cartella denominata
app
che contiene un numero di file di codice e una sottocartella. Di questi, si lavora spesso conviews.py
(che contiene le funzioni che definiscono le pagine nell'app Web) emodels.py
(che contiene classi che definiscono gli oggetti dati). Lamigrations
cartella viene usata dall'utilità di amministrazione di Django per gestire le versioni del database, come illustrato più avanti in questa esercitazione. Esistono anche i fileapps.py
(configurazione dell'app),admin.py
(per la creazione di un'interfaccia amministrativa) etests.py
(per unit test), che non sono trattati qui.All'interno
app/settings.py
di aggiungere il codice seguente e impostare valori CLIENT_ID, CLIENT_SECRET, DEVELOPER_TOKEN e ENVIRONMENT personalizzati.""" 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
All'interno di
app/settings.py
aggiungiapp
all'elenco delle app installate.INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app', ]
Nel terminale di VS Code creare le
app/static/app
cartelle eapp/templates/app
:(env) PS C:\dev\hello_django> mkdir app/static/app (env) PS C:\dev\hello_django> mkdir app/templates/app
All'interno delle
app/static/app
cartelle creare un nuovo file denominato site.css e aggiungere il contenuto seguente..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%; }
All'interno della
app/templates/app
cartella creare un file,index.html
con il contenuto seguente.{% 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://video2.skills-academy.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 %}
All'interno della
app/templates/app
cartella creare un file,layout.html
con il contenuto seguente.<!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>
All'interno della
app/templates/app
cartella creare un file,login.html
con il contenuto seguente.{% 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 %}
All'interno della
app/templates/app
cartella creare un file,loginpartial.html
con il contenuto seguente.{% 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 %}
All'interno della
app
cartella creare un file,forms.py
con il contenuto seguente.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'}))
Modificare
app/models.py
in modo che corrisponda al codice seguente.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
Modificare
app/views.py
in modo che corrisponda al codice seguente.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
Sostituire il contenuto di
web_project/urls.py
con il contenuto seguente. Ilurls.py
file è il punto in cui si specificano i modelli per instradare URL diversi alle visualizzazioni appropriate. Ad esempio, il codice seguente esegue il mapping dell'URL radice dell'app (""
) allahome
funzione appena aggiunta aapp/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), ]
Salvare tutti i file modificati con
Ctrl+K S
.Eseguire
python manage.py makemigrations
per generare script nella cartella migrazioni che eseguono la migrazione del database dal relativo stato corrente al nuovo stato.Eseguire
python manage.py migrate
per applicare gli script al database effettivo. Gli script di migrazione registrano in modo efficace tutte le modifiche incrementali apportate ai modelli di dati (models.py
) nel tempo. Applicando le migrazioni, Django aggiorna il database in modo che corrisponda ai modelli. Poiché ogni modifica incrementale ha un proprio script, Django può eseguire automaticamente la migrazione di qualsiasi versione precedente di un database (incluso un nuovo database) alla versione corrente. Di conseguenza, è necessario preoccuparsi solo dei modelli in models.py, mai dello schema del database sottostante o degli script di migrazione. Hai permesso a Django di fare quella parte!Creare un account utente avanzato nell'app aprendo un terminale in VS Code per l'ambiente virtuale, quindi eseguendo il comando
python manage.py createsuperuser --username=<username> --email=<email>
, sostituendo<username>
e<email>
, ovviamente, con le informazioni personali. Quando si esegue il comando, Django richiede di immettere e confermare la password.Importante
Assicurarsi di ricordare la combinazione di nome utente e password. Queste sono le credenziali usate per eseguire l'autenticazione nel portale di amministrazione dell'app Web.
Nel terminale di VS Code, di nuovo con l'ambiente virtuale attivato, eseguire il server di sviluppo con
python manage.py runserver
e aprire un browser perhttp://127.0.0.1:8000/
visualizzare una pagina che esegue il rendering di "Hello, Django".Nel Web browser passare a
http://127.0.0.1:8000/admin/
e creare un nuovo utente Web Django in Utenti. Ciò è diverso dalle credenziali utente di Microsoft Advertising, in modo che più utenti di Microsoft Advertising possano accedere all'app separatamente.Accedere con il nuovo utente (non l'amministratore con privilegi avanzati) e dovrebbe essere visualizzata l'opzione per l'autenticazione con un account Microsoft.
Dopo aver fatto clic su Autentica account Microsoft , verrà richiesto di concedere le autorizzazioni dell'app Web per gestire gli account Microsoft Advertising. Se si acconsente e si ha accesso agli account Microsoft Advertising, si dovrebbe essere reindirizzati a una visualizzazione dei nomi e degli ID dell'account.