Freigeben über


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.

  1. Erstellen Sie in Ihrem Dateisystem einen Projektordner für dieses Tutorial, z hello_django. B. .

  2. Öffnen Sie im hello_django Ordner PowerShell oder Ihre bevorzugte Skriptshell, und verwenden Sie den folgenden Befehl, um eine virtuelle Umgebung namens env basierend auf Ihrem aktuellen Interpreter zu erstellen:

    py -3 -m venv env
    
  3. Öffnen Sie den hello_django Projektordner in VS Code, indem Sie code .ausführen oder VS Code ausführen und den Befehl Dateiordner>öffnen verwenden.

    Öffnen von VS Code

  4. Öffnen Sie in VS Code die Befehlspalette (Befehlspalette anzeigen> oder Ctrl+Shift+P). Wählen Sie dann den Befehl Python: Interpreter auswählen aus.

  5. 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 .\envbeginnt:

    Auswählen der virtuellen Umgebung für Python

  6. 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:

    Die ausgewählte Umgebung wird in der VS Code-status-Leiste

  7. Installieren Sie Django in der virtuellen Umgebung über pip im VS Code-Terminal:

    python -m pip install django
    
  8. 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-admindas bei der Installation des Django-Pakets installiert wird.

Erstellen des Django-Projekts

  1. 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 aus python 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.

      Django-Webprojekt

  2. 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.sqlite3erstellt, 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. Das wsgi.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. .

  3. Ctrl+click die http://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.

    Standardansicht eines leeren Django-Projekts

  4. 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

  1. Führen Sie im VS Code-Terminal mit aktivierter virtueller Umgebung den Befehl des startapp Verwaltungshilfsprogramms in Ihrem Projektordner (in dem manage.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 mit views.py (die Funktionen enthält, die Seiten in Ihrer Web-App definieren) und models.py (die Klassen enthält, die Ihre Datenobjekte definieren). Der migrations Ordner wird vom Verwaltungshilfsprogramm von Django zum Verwalten von Datenbankversionen verwendet, wie weiter unten in diesem Tutorial erläutert. Es gibt auch die Dateien apps.py (App-Konfiguration), admin.py (zum Erstellen einer Verwaltungsschnittstelle) und tests.py (für Komponententests), die hier nicht behandelt werden.

  2. 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
    
  3. Fügen Sie in app/settings.py der Liste der installierten Apps hinzu app .

        INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app',
    ]
    
  4. Erstellen Sie im VS Code-Terminal die app/static/app Ordner und app/templates/app :

    (env) PS C:\dev\hello_django> mkdir app/static/app
    (env) PS C:\dev\hello_django> mkdir app/templates/app 
    
  5. 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%;
    }
    
  6. Erstellen Sie innerhalb des app/templates/app Ordners eine Datei index.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 &raquo;</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 &raquo;</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 &raquo;</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 &raquo;</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 &raquo;</a></p>
        </div>
    </div>
    {% endblock %}
    {% block scripts %}
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'app/site.css' %}"/>
    {% endblock %}
    
  7. Erstellen Sie innerhalb des app/templates/app Ordners eine Datei layout.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>&copy; {{ year }} - My Django Application</p>
            </footer>
        </div>
    {% block scripts %}{% endblock %}
    </body>
    </html>
    
  8. Erstellen Sie innerhalb des app/templates/app Ordners eine Datei login.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 %}
    
  9. Erstellen Sie innerhalb des app/templates/app Ordners eine Datei loginpartial.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 %}
    
  10. Erstellen Sie innerhalb des app Ordners eine Datei forms.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'}))
    
  11. Ä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
    
  12. Ä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
    
  13. Ersetzen Sie den Inhalt von web_project/urls.py durch den folgenden Inhalt. In urls.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 ("") der home Funktion zu, die Sie gerade hinzugefügt haben app/views.py:

    from django.contrib import admin
    from django.urls import path
    from app import views as app_views
    from django.contrib.auth import views as auth_views
    from datetime import datetime
    from django.conf.urls import include, url
    from app.forms import BootstrapAuthenticationForm
    from django.contrib.auth.views import HttpResponseRedirect
    
    from django.contrib import admin
    admin.autodiscover()
    
    urlpatterns = [
        url(r'^applogout', app_views.applogout, name='applogout'),
        url(r'^callback', app_views.callback, name='callback'),
        url(r'^revoke', app_views.revoke, name='revoke'),
        url(r'^$', app_views.home, name='home'),
        url(r'^login/$',
            auth_views.LoginView.as_view(
                template_name='app/login.html', 
                authentication_form=BootstrapAuthenticationForm,
                extra_context= {
                    'title':'Log in',
                    'year':datetime.now().year,
                }
            ),
            name='login'),
        url(r'^logout$',
            auth_views.LogoutView.as_view(),
            {
                'next_page': '/',
            },
            name='logout'),
    
        url(r'^admin/', admin.site.urls),
    ]
    
  14. Speichern Sie alle geänderten Dateien mit Ctrl+K S.

  15. 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.

  16. 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!

  17. 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.

  18. 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 anzuzeigen http://127.0.0.1:8000/ , auf der "Hello, Django" gerendert wird.

  19. 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.

    Django Admin

  20. Melden Sie sich mit dem neuen Benutzer (nicht mit dem Superadministrator) an. Daraufhin sollte die Option zur Authentifizierung mit einem Microsoft-Konto angezeigt werden.

    Authentifizieren eines Microsoft-Kontos Authentifizieren

  21. 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