Tutorial: Aplicación web de api de Bing Ads en Python
En este tutorial se explica cómo empezar a ejecutar una aplicación web de Microsoft Advertising mediante el SDK de Python de Bing Ads, el IDE de Visual Studio Code y el marco web de Django.
En este tutorial no se exploran varios detalles sobre django, como trabajar con modelos de datos y crear una interfaz administrativa. Para obtener instrucciones sobre esos aspectos, consulte la documentación de Django. Para obtener más información sobre cómo trabajar con Django en el terminal, editor y depurador de VS Code, consulte Uso de Django en Visual Studio Code. En este tutorial se toma en serio las instrucciones de configuración de Uso de Django en Visual Studio Code.
Introducción a la aplicación web de ejemplo
Al final de este tutorial, tendrá una aplicación web en ejecución en http://localhost la que autenticará sus credenciales de usuario de Microsoft Advertising y mostrará la información de usuario y cuentas. A continuación, puede agregar varios usuarios de aplicaciones web, que pueden habilitar el acceso para que la aplicación use sus credenciales de Microsoft Advertising. Esta aplicación web proporciona una asignación de uno a uno de un usuario de aplicación web, por ejemplo, ContosoUser a un usuario de Microsoft Advertising. Para obtener información sobre cómo modificar el modelo de datos, consulte la documentación de Django para obtener más información. Si el usuario de la aplicación web permite el acceso a sus cuentas de Microsoft Advertising con una cuenta de Microsoft, se almacena un token de actualización en la base de datos SQL Lite del servidor web.
Requisitos previos
Tendrá que tener instalado Visual Studio Code para seguir este tutorial. Para ejecutar la aplicación web de Django, puede usar Visual Studio Community o Visual Studio Professional; sin embargo, los pasos de configuración variarán de los de este tutorial.
Tendrá que tener Python 3 instalado desde python.org; Normalmente, use el botón Descargar Python 3.7.0 que aparece primero en la página (o lo que sea la versión más reciente). En Windows, asegúrese de que la ubicación del intérprete de Python está incluida en la variable de entorno PATH. Para comprobarlo, ejecute path
en el símbolo del sistema. Si no se incluye la carpeta del intérprete de Python, abra Configuración de Windows, busque "entorno", seleccione Editar variables de entorno para la cuenta y, a continuación, edite la variable Path para incluir esa carpeta.
Tendrá que instalar el SDK de Python de Bing Ads y este tutorial le guiará por la instalación.
Necesitará el marco web de Django instalado para implementar la aplicación localmente y este tutorial le guiará por la instalación.
Necesitará al menos un usuario con credenciales de Microsoft Advertising y un token de desarrollador.
Tendrá que registrar una aplicación y tomar nota del identificador de cliente (id. de aplicación registrado) y del secreto de cliente (contraseña registrada). Tendrá que registrar una aplicación web (no nativa) para este ejemplo. Se le pedirá que registre una o varias direcciones URL de redireccionamiento y, para este tutorial, debe registrar http://localhost/callback. En su lugar, debe usar https cuando se implemente en un servidor de producción. Para obtener más información sobre cómo registrar una aplicación y el flujo de concesión de código de autorización, consulte Autenticación con OAuth.
Este tutorial se desarrolló en Windows. Aunque Windows no es necesario para ejecutar el ejemplo, algunos de los pasos siguientes variarán si usa otro sistema operativo, por ejemplo, Linux o MacOS.
Creación de un entorno de proyecto para Django
En esta sección creará un entorno virtual en el que django está instalado. El uso de un entorno virtual evita la instalación de Django en un entorno de Python global y proporciona un control exacto sobre las bibliotecas usadas en una aplicación.
En el sistema de archivos, cree una carpeta de proyecto para este tutorial, como
hello_django
.En la
hello_django
carpeta, abra PowerShell o el shell de script favorito y use el siguiente comando para crear un entorno virtual denominadoenv
basado en el intérprete actual:py -3 -m venv env
Abra la carpeta del
hello_django
proyecto en VS Code ejecutandocode .
o ejecutando VS Code y usando el comando Abrircarpeta de archivo>.En VS Code, abra la paleta de comandos (Ver>paleta de comandos o
Ctrl+Shift+P
). A continuación, seleccione el comando Python: Select Interpreter (Python: seleccionar intérprete ).El comando presenta una lista de intérpretes disponibles que VS Code puede localizar automáticamente. La lista variará; Si no ve el intérprete deseado, consulte Configuración de entornos de Python. En la lista, seleccione el entorno virtual en la carpeta del proyecto que comienza con
./env
o.\env
:Ejecutar terminal: nuevo terminal (
Ctrl+Shift+ `
) desde la paleta de comandos, que crea un terminal y activa automáticamente el entorno virtual mediante la ejecución de su script de activación.Nota:
En Windows, si el tipo de terminal predeterminado es PowerShell, es posible que vea un error que indica que no se puede ejecutar activate.ps1 porque la ejecución de scripts está deshabilitada en el sistema. El error debe proporcionar un vínculo para obtener información sobre cómo permitir scripts. De lo contrario, use Terminal: seleccione Default Shell (Shell predeterminado) para establecer el valor predeterminado que prefiera.
El entorno seleccionado aparece en la esquina inferior izquierda de la barra de estado de VS Code. Observe el indicador (venv) que le indica que usa un entorno virtual:
Instale Django en el entorno virtual a través de pip en el terminal de VS Code:
python -m pip install django
Instale el SDK de Python de Bing Ads en el entorno virtual a través de pip en el terminal de VS Code:
python -m pip install bingads
Ahora tiene un entorno virtual independiente listo para escribir código de Django y Microsoft Advertising.
Creación y ejecución de una aplicación de Django
En la terminología de Django, un "proyecto de Django" se compone de varios archivos de configuración de nivel de sitio junto con una o varias "aplicaciones" que se implementan en un host web para crear una aplicación web completa. Un proyecto de Django puede contener varias aplicaciones, cada una de las cuales normalmente tiene una función independiente en el proyecto, y la misma aplicación puede estar en varios proyectos de Django. Una aplicación, por su parte, es solo un paquete de Python que sigue ciertas convenciones que Django espera.
Para crear una aplicación de Django, es necesario crear primero el proyecto de Django para que actúe como contenedor de la aplicación y, a continuación, crear la propia aplicación. Para ambos propósitos, use la utilidad administrativa de Django, django-admin
, que se instala al instalar el paquete de Django.
Creación del proyecto de Django
En el terminal de VS Code donde está activado el entorno virtual, ejecute el siguiente comando:
django-admin startproject web_project .
Este
startproject
comando supone (mediante el uso de.
al final) que la carpeta actual es la carpeta del proyecto y crea lo siguiente en ella:manage.py
: utilidad administrativa de la línea de comandos de Django para el proyecto. Ejecute comandos administrativos para el proyecto mediantepython manage.py <command> [options]
.Subcarpeta denominada
web_project
, que contiene los siguientes archivos:-
__init__.py
: un archivo vacío que indica a Python que esta carpeta es un paquete de Python. -
wsgi.py
: un punto de entrada para que los servidores web compatibles con WSGI sirvan al proyecto. Normalmente, este archivo se deja tal como está, ya que proporciona los enlaces para los servidores web de producción. -
settings.py
: contiene la configuración del proyecto de Django, que se modifica durante el desarrollo de una aplicación web. -
urls.py
: contiene una tabla de contenido para el proyecto de Django, que también se modifica en el transcurso del desarrollo.
-
Para comprobar el proyecto de Django, asegúrese de que el entorno virtual está activado y, a continuación, inicie el servidor de desarrollo de Django mediante el comando
python manage.py runserver
. El servidor se ejecuta en el puerto predeterminado 8000 y verá una salida similar a la siguiente en la ventana de salida del terminal de 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.
Cuando se ejecuta el servidor por primera vez, se crea una base de datos SQLite predeterminada en el archivo
db.sqlite3
, que generalmente está pensada para fines de desarrollo, pero se puede usar en producción para aplicaciones web de bajo volumen. Además, el servidor web integrado de Django está diseñado solo para fines de desarrollo local. Sin embargo, al implementar en un host web, Django usa el servidor web del host en su lugar. Elwsgi.py
módulo del proyecto de Django se encarga de conectarse a los servidores de producción.Si desea usar un puerto diferente al 8000 predeterminado, simplemente especifique el número de puerto en la línea de comandos, como
python manage.py runserver 5000
.Ctrl+click
lahttp://127.0.0.1:8000/
dirección URL de la ventana de salida del terminal de VS Code para abrir el explorador predeterminado en esa dirección. Si Django está instalado correctamente y el proyecto es válido, verá la página predeterminada que se muestra a continuación. La ventana Salida de VS Code también muestra el registro del servidor.Cuando haya terminado, cierre la ventana del explorador y detenga el servidor en VS Code mediante
Ctrl+C
como se indica en la ventana de salida del terminal de VS Code.
Creación de una aplicación de Django para Microsoft Advertising
En el terminal de VS Code con el entorno virtual activado, ejecute el comando de la utilidad administrativa en la carpeta del
startapp
proyecto (dondemanage.py
reside):python manage.py startapp app
El comando crea una carpeta denominada
app
que contiene varios archivos de código y una subcarpeta. De ellos, suele trabajar conviews.py
(que contiene las funciones que definen páginas en la aplicación web) ymodels.py
(que contiene clases que definen los objetos de datos). La utilidad administrativa de Django usa lamigrations
carpeta para administrar las versiones de la base de datos, como se describe más adelante en este tutorial. También están los archivosapps.py
(configuración de la aplicación),admin.py
(para crear una interfaz administrativa) ytests.py
(para pruebas unitarias), que no se tratan aquí.En ,
app/settings.py
agregue el código siguiente y establezca sus propios valores de CLIENT_ID, CLIENT_SECRET, DEVELOPER_TOKEN y ENVIRONMENT .""" 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
En
app/settings.py
, agregueapp
a la lista de aplicaciones instaladas.INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app', ]
En el terminal de VS Code, cree las
app/static/app
carpetas yapp/templates/app
:(env) PS C:\dev\hello_django> mkdir app/static/app (env) PS C:\dev\hello_django> mkdir app/templates/app
En las
app/static/app
carpetas, cree un nuevo archivo denominado site.css y agregue el siguiente contenido..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%; }
En la
app/templates/app
carpeta, cree un archivo,index.html
con el contenido siguiente.{% 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 %}
En la
app/templates/app
carpeta, cree un archivo,layout.html
con el contenido siguiente.<!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>
En la
app/templates/app
carpeta, cree un archivo,login.html
con el contenido siguiente.{% 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 %}
En la
app/templates/app
carpeta, cree un archivo,loginpartial.html
con el contenido siguiente.{% 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 %}
En la
app
carpeta, cree un archivo,forms.py
con el contenido siguiente.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'}))
Modifique
app/models.py
para que coincida con el código siguiente.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
Modifique
app/views.py
para que coincida con el código siguiente.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
Reemplace el contenido de
web_project/urls.py
por el contenido siguiente. Elurls.py
archivo es donde se especifican patrones para enrutar distintas direcciones URL a sus vistas adecuadas. Por ejemplo, el código siguiente asigna la dirección URL raíz de la aplicación (""
) a lahome
función que acaba de agregar 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), ]
Guarde todos los archivos modificados con
Ctrl+K S
.Ejecute
python manage.py makemigrations
para generar scripts en la carpeta de migraciones que migra la base de datos de su estado actual al nuevo estado.Ejecute
python manage.py migrate
para aplicar los scripts a la base de datos real. Los scripts de migración registran de forma eficaz todos los cambios incrementales realizados en los modelos de datos (models.py
) a lo largo del tiempo. Al aplicar las migraciones, Django actualiza la base de datos para que coincida con los modelos. Dado que cada cambio incremental tiene su propio script, Django puede migrar automáticamente cualquier versión anterior de una base de datos (incluida una nueva base de datos) a la versión actual. Como resultado, solo necesita preocuparse por los modelos de models.py, nunca con el esquema de base de datos subyacente ni con los scripts de migración. ¡Dejas que Django haga esa parte!Cree una cuenta de superusuario en la aplicación abriendo un Terminal en VS Code para el entorno virtual y, a continuación, ejecutando el comando
python manage.py createsuperuser --username=<username> --email=<email>
, reemplazando<username>
y<email>
, por supuesto, con su información personal. Al ejecutar el comando, Django le pide que escriba y confirme la contraseña.Importante
Asegúrese de recordar la combinación de nombre de usuario y contraseña. Estas son las credenciales que se usan para autenticarse en el portal de administración de la aplicación web.
En el terminal de VS Code, de nuevo con el entorno virtual activado, ejecute el servidor de desarrollo con
python manage.py runserver
y abra un explorador parahttp://127.0.0.1:8000/
ver una página que represente "Hello, Django".En el explorador web, vaya a
http://127.0.0.1:8000/admin/
y cree un nuevo usuario web de Django en Usuarios. Esto es distinto de las credenciales de usuario de Microsoft Advertising, de modo que varios usuarios de Microsoft Advertising puedan iniciar sesión en la aplicación por separado.Inicie sesión con el nuevo usuario (no con el superadministrador) y debería ver la opción para autenticarse con una cuenta de Microsoft.
Después de hacer clic en Autenticar cuenta microsoft , se le pedirá que conceda permisos a su propia aplicación web para administrar sus cuentas de Microsoft Advertising. Si da su consentimiento y tiene acceso a cuentas de Microsoft Advertising, se le redirigirá a una vista de los nombres de cuenta y los identificadores.