Aracılığıyla paylaş


İzlenecek Yol: Python'da Bing Ads API Web Uygulaması

Bu öğreticide Bing Ads Python SDK'sını, Visual Studio Code IDE'yi ve Django web çerçevesini kullanarak bir Microsoft Advertising web uygulamasını çalıştırmaya başlamayı öğreneceksiniz.

Bu öğretici, veri modelleriyle çalışma ve yönetim arabirimi oluşturma gibi Django'yla ilgili çeşitli ayrıntıları incelemez. Bu konuda rehberlik için Django belgelerine bakın. VS Code terminalinde, düzenleyicide ve hata ayıklayıcıda Django ile çalışma hakkında daha fazla bilgi için bkz. Visual Studio Code'de Django kullanma. Bu öğretici, Visual Studio Code'de Django kullanma başlığındaki kurulum yönergelerinden büyük ölçüde yararlanıyor.

Örnek Web Uygulamasına Genel Bakış

Bu öğreticinin sonunda üzerinde çalışan http://localhost ve Microsoft Advertising kullanıcı kimlik bilgilerinizi doğrulayacak ve kullanıcı ve hesap bilgilerinizi görüntüleyen bir web uygulamanız olacak. Ardından, uygulamanızın Microsoft Advertising kimlik bilgilerini kullanması için erişimi etkinleştirebilecek birden çok web uygulaması kullanıcısı ekleyebilirsiniz. Bu web uygulaması bir web uygulaması kullanıcısının bire bir eşlemesini sağlar; örneğin ContosoUser ile Microsoft Advertising kullanıcısı. Veri modelini değiştirme hakkında daha fazla bilgi için lütfen Django belgelerine bakın . Web uygulaması kullanıcınız Microsoft Advertising hesaplarına bir Microsoft hesabıyla erişim sağlıyorsa, web sunucunuzdaki SQL Lite veritabanında bir yenileme belirteci depolanır.

Önkoşullar

Bu öğreticiyi izlemek için Visual Studio Code yüklemeniz gerekir. Django web uygulamasını çalıştırmak için Visual Studio Community veya Visual Studio Professional kullanabilirsiniz; ancak kurulum adımları bu öğreticideki adımlardan farklı olacaktır.

python.org'dan Python 3'ü yüklemeniz gerekir; genellikle sayfada ilk görüntülenen Python 3.7.0'ı İndir düğmesini (veya en son sürüm hangisiyse) kullanın. Windows'da Python yorumlayıcınızın konumunun PATH ortam değişkeninize eklendiğinden emin olun. Komut isteminde komutunu çalıştırarak path bunu de kontrol edebilirsiniz. Python yorumlayıcısının klasörü dahil değilse Windows Ayarları'nı açın, "ortam" araması yapın, Hesabınız için ortam değişkenlerini düzenle'yi seçin ve ardından Path değişkenini bu klasörü içerecek şekilde düzenleyin.

Bing Ads Python SDK'sınıyüklemeniz gerekir ve bu öğretici yükleme işleminde size yol gösterir.

Uygulamayı yerel olarak dağıtmak için Django web çerçevesinin yüklü olması gerekir ve bu öğretici yüklemede size yol gösterir.

Microsoft Advertising kimlik bilgileri ve geliştirici belirteci olan en az bir kullanıcıya ihtiyacınız olacaktır.

Bir uygulamayı kaydetmeniz ve istemci kimliğini (kayıtlı uygulama kimliği) ve istemci gizli anahtarını (kayıtlı parola) not almanız gerekir. Bu örnek için bir web uygulaması (yerel değil) kaydetmeniz gerekir. Bir veya daha fazla yeniden yönlendirme URL'sini kaydetmeniz istenir ve bu öğretici için kaydetmeniz http://localhost/callbackgerekir. Bunun yerine üretim sunucusuna dağıtılırken https kullanmalısınız. Bir uygulamayı kaydetme ve yetkilendirme kodu verme akışı hakkında daha fazla bilgi için bkz. OAuth ile kimlik doğrulaması.

Bu öğretici Windows üzerinde geliştirilmiştir. Örneği çalıştırmak için Windows gerekli olmasa da, Linux veya MacOS gibi başka bir işletim sistemi kullanıyorsanız aşağıdaki adımlardan bazıları farklılık gösterir.

Django için proje ortamı oluşturma

Bu bölümde Django'nun yüklü olduğu bir sanal ortam oluşturacaksınız. Sanal ortam kullanmak Django'yu genel bir Python ortamına yüklemeyi önler ve bir uygulamada kullanılan kitaplıklar üzerinde tam denetim sağlar.

  1. Dosya sisteminizde, bu öğretici için gibi hello_djangobir proje klasörü oluşturun.

  2. hello_django klasöründe Powershell'i veya sık kullandığınız betik kabuğunu açın ve geçerli yorumlayıcınızı temel alan adlı env bir sanal ortam oluşturmak için aşağıdaki komutu kullanın:

    py -3 -m venv env
    
  3. hello_django vs code komutunu çalıştırarak veya VS Code çalıştırarak code .ve Dosya>Klasör Aç komutunu kullanarak proje klasörünü VS Code'da açın.

    VS Code'un

  4. VS Code'da Komut Paleti'ni açın (Komut PaletiniGörüntüle> veya Ctrl+Shift+P). Ardından Python: Yorumlayıcı'ya tıklayın komutunu seçin.

  5. komutu, VS Code'un otomatik olarak bulabileceği kullanılabilir yorumlayıcıların listesini sunar. Listenize göre değişiklik gösterir; İstenen yorumlayıcıyı görmüyorsanız bkz. Python ortamlarını yapılandırma. Listeden, proje klasörünüzde veya .\envile ./env başlayan sanal ortamı seçin:

    Python için sanal ortamı seçme Python için

  6. Terminali Çalıştır: Komut Paleti'nden Yeni Terminal (Ctrl+Shift+ ` ), bir terminal oluşturur ve etkinleştirme betiğini çalıştırarak sanal ortamı otomatik olarak etkinleştirir.

    Not

    Windows'ta varsayılan terminal türünüz PowerShell ise, sistemde betik çalıştırma devre dışı bırakıldığından activate.ps1 çalıştıramadığı bir hata görebilirsiniz. Hata, betiklere izin verme hakkında bilgi için bir bağlantı sağlamalıdır. Aksi takdirde, Tercih ettiğiniz varsayılanı ayarlamak için Terminal: Varsayılan Kabuk'a tıklayın .

    Seçilen ortam VS Code durum çubuğunun sol alt köşesinde görüntülenir. Sanal ortam kullandığınızı belirten (venv) göstergesine dikkat edin:

    VS Code durum çubuğunda gösterilen seçili ortam VS

  7. Django'yu VS Code Terminali'ndeki pip aracılığıyla sanal ortama yükleyin:

    python -m pip install django
    
  8. Bing Ads Python SDK'sını VS Code Terminali'ndeki pip aracılığıyla sanal ortama yükleyin:

    python -m pip install bingads
    

Artık Django ve Microsoft Advertising kodu yazmaya hazır bağımsız bir sanal ortamınız var.

Django uygulaması oluşturma ve çalıştırma

Django terminolojisinde bir "Django projesi", tam bir web uygulaması oluşturmak için bir web konağına dağıttığınız bir veya daha fazla "uygulama" ile birlikte birkaç site düzeyinde yapılandırma dosyasından oluşur. Bir Django projesi, her biri genellikle projede bağımsız bir işleve sahip olan birden çok uygulama içerebilir ve aynı uygulama birden çok Django projesinde olabilir. Bir uygulama, Django'nın beklediği belirli kuralları izleyen bir Python paketidir.

Bir Django uygulaması oluşturmak için önce uygulamanın kapsayıcısı olarak hizmet vermek üzere Django projesini oluşturmak, ardından uygulamanın kendisini oluşturmak gerekir. Her iki amaçla da Django paketini yüklediğinizde yüklenen Django yönetim yardımcı programını django-adminkullanırsınız.

Django projesini oluşturma

  1. Sanal ortamınızın etkinleştirildiği VS Code Terminali'nde aşağıdaki komutu çalıştırın:

    django-admin startproject web_project .
    

    Bu startproject komut geçerli klasörün proje klasörünüz olduğunu varsayar (sonunda öğesini kullanarak . ) ve içinde aşağıdakileri oluşturur:

    • manage.py: Proje için Django komut satırı yönetim yardımcı programı. kullanarak python manage.py <command> [options]proje için yönetim komutlarını çalıştırırsınız.

    • Aşağıdaki dosyaları içeren adlı web_projectbir alt klasör:

      • __init__.py: Python'a bu klasörün bir Python paketi olduğunu bildiren boş bir dosya.
      • wsgi.py: WSGI uyumlu web sunucularının projenize hizmet vermeleri için bir giriş noktası. Genellikle bu dosyayı üretim web sunucuları için kancaları sağladığından olduğu gibi bırakırsınız.
      • settings.py: bir web uygulaması geliştirirken değiştirdiğiniz Django projesinin ayarlarını içerir.
      • urls.py: Geliştirme sürecinde de değiştirdiğiniz Django projesi için bir içindekiler tablosu içerir.

      Django Web Projesi

  2. Django projesini doğrulamak için sanal ortamınızın etkinleştirildiğinden emin olun ve komutunu python manage.py runserverkullanarak Django'nun geliştirme sunucusunu başlatın. Sunucu varsayılan 8000 numaralı bağlantı noktasında çalışır ve VS Code terminal çıkış penceresinde aşağıdakine benzer bir çıkış görürsünüz:

    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.
    

    Sunucuyu ilk kez çalıştırdığınızda, dosyasında db.sqlite3genellikle geliştirme amaçlı olan ancak düşük hacimli web uygulamaları için üretimde kullanılabilen varsayılan bir SQLite veritabanı oluşturur. Ayrıca Django'nun yerleşik web sunucusu yalnızca yerel geliştirme amacıyla tasarlanmıştır. Ancak bir web konağına dağıttığınızda Django bunun yerine konağın web sunucusunu kullanır. wsgi.py Django projesindeki modül, üretim sunucularına bağlanma işlemini üstlenir.

    Varsayılan 8000'den farklı bir bağlantı noktası kullanmak istiyorsanız, komut satırında python manage.py runserver 5000gibi bağlantı noktası numarasını belirtmeniz yeterlidir.

  3. Ctrl+click http://127.0.0.1:8000/ varsayılan tarayıcınızı bu adrese açmak için VS Code terminal çıkış penceresindeki URL'yi seçin. Django doğru yüklendiyse ve proje geçerliyse, aşağıda gösterilen varsayılan sayfayı görürsünüz. VS Code Çıktısı penceresinde sunucu günlüğü de gösterilir.

    Boş Django projesinin varsayılan görünümü

  4. İşiniz bittiğinde tarayıcı penceresini kapatın ve VS Code terminal çıkış penceresinde gösterildiği gibi kullanarak Ctrl+C VS Code'da sunucuyu durdurun.

Microsoft Advertising için Django uygulaması oluşturma

  1. Sanal ortamınızın etkinleştirildiği VS Code Terminali'nde startapp , yönetim yardımcı programının komutunu proje klasörünüzde (burada manage.py bulunur) çalıştırın:

    python manage.py startapp app
    

    komutu, bir dizi kod dosyası ve bir alt klasör içeren adlı app bir klasör oluşturur. Bunlardan sık sık (web uygulamanızdaki sayfaları tanımlayan işlevleri içeren) ve models.py (veri nesnelerinizi tanımlayan sınıfları içeren) ile views.py çalışırsınız. Klasör migrations , bu öğreticinin ilerleyen bölümlerinde açıklandığı gibi veritabanı sürümlerini yönetmek için Django'nun yönetim yardımcı programı tarafından kullanılır. Burada ele alınmayan dosyalar apps.py (uygulama yapılandırması), admin.py (yönetim arabirimi oluşturmak için) ve tests.py (birim testleri için) de vardır.

  2. içinde app/settings.py aşağıdaki kodu ekleyin ve kendi CLIENT_ID, CLIENT_SECRET, DEVELOPER_TOKEN ve ORTAM değerlerinizi ayarlayın.

    """
    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. içinde app/settings.py yüklü uygulamalar listesine ekleyin app .

        INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app',
    ]
    
  4. VS Code Terminali'nde ve app/templates/app klasörlerini app/static/app oluşturun:

    (env) PS C:\dev\hello_django> mkdir app/static/app
    (env) PS C:\dev\hello_django> mkdir app/templates/app 
    
  5. Klasörlerin app/static/app içinde site.css adlı yeni bir dosya oluşturun ve aşağıdaki içeriği ekleyin.

    .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. Klasörün içinde app/templates/app , index.html aşağıdaki içerikle birlikte bir dosya oluşturun.

    {% 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. Klasörün içinde app/templates/app , layout.html aşağıdaki içerikle birlikte bir dosya oluşturun.

    <!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. Klasörün içinde app/templates/app , login.html aşağıdaki içerikle birlikte bir dosya oluşturun.

    {% 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. Klasörün içinde app/templates/app , loginpartial.html aşağıdaki içerikle birlikte bir dosya oluşturun.

    {% 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. Klasörün içinde app , forms.py aşağıdaki içerikle birlikte bir dosya oluşturun.

    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. Aşağıdaki kodla eşleşecek şekilde değiştirin app/models.py .

    from django.db import models
    from django.contrib.auth.models import User
    
    # In this web app a Microsoft Advertising user maps a Django web user to a refresh token.
    
    class BingAdsUser(models.Model):
        user = models.OneToOneField(User, on_delete=models.PROTECT)
        refresh_token = models.CharField(max_length=200)
    
        # def __unicode__(self):              # __unicode__ on Python 2
        #     return self.refresh_token
        def __str__(self):              # __str__ on Python 3
            return self.refresh_token
    
  12. Aşağıdaki kodla eşleşecek şekilde değiştirin app/views.py .

    from django.http import HttpRequest, HttpResponse
    from django.shortcuts import render
    from django.template.loader import get_template, render_to_string
    from web_project import settings
    from datetime import datetime
    from django.shortcuts import redirect
    from django.contrib.auth import authenticate, login, logout, get_user_model
    from django.contrib.auth.models import User
    from app.models import BingAdsUser
    from bingads import *
    
    # import logging
    # logging.basicConfig(level=logging.INFO)
    # logging.getLogger('suds.client').setLevel(logging.DEBUG)
    # logging.getLogger('suds.transport').setLevel(logging.DEBUG)
    
    authorization_data = AuthorizationData(
        account_id=None, 
        customer_id=None, 
        developer_token=None, 
        authentication=None)
    
    customer_service=None
    
    def home(request):
        """
        If an authenticated user returns to this page after logging in, the appropriate 
        context is provided to index.html for rendering the page. 
        """
        assert isinstance(request, HttpRequest)
    
        # If the Django user has a refresh token stored, 
        # try to use it to get Microsoft Advertising data.
        if user_has_refresh_token(request.user.username):
            return redirect('/callback')
        else:
            return render(
                request,
                'app/index.html'
            )
    
    def callback(request):
        """Handles OAuth authorization, either via callback or direct refresh request."""
        assert isinstance(request, HttpRequest)
    
        authentication = OAuthWebAuthCodeGrant(
            client_id=settings.CLIENT_ID,
            client_secret=settings.CLIENT_SECRET, 
            redirection_uri=settings.REDIRECTION_URI,
            env=settings.ENVIRONMENT)
    
        return authorize_bing_ads_user(request, authentication)
    
    def authorize_bing_ads_user(request, authentication):
        assert isinstance(request, HttpRequest)
    
        global customer_service
        bingadsuser = None
    
        try:
            Users = get_user_model()
            user = User.objects.get(username=request.user.username)
        except User.DoesNotExist:
            return render(
                request,
                'app/index.html'
            )
    
        try:
            bingadsuser = user.bingadsuser
        except BingAdsUser.DoesNotExist:
            bingadsuser = BingAdsUser()
            bingadsuser.user = user
            pass
    
        try:
            # If we have a refresh token let's refresh the access token.
            if(bingadsuser is not None and bingadsuser.refresh_token != ""):
                authentication.request_oauth_tokens_by_refresh_token(bingadsuser.refresh_token)
                bingadsuser.refresh_token = authentication.oauth_tokens.refresh_token
    
            # If the current HTTP request is a callback from the Microsoft Account authorization server,
            # use the current request url containing authorization code to request new access and refresh tokens.
            elif (request.GET.get('code') is not None):
                authentication.request_oauth_tokens_by_response_uri(response_uri = request.get_full_path()) 
                bingadsuser.refresh_token = authentication.oauth_tokens.refresh_token
        except OAuthTokenRequestException:
            bingadsuser.refresh_token = ""  
    
        user.save()
        bingadsuser.save()
    
        # If there is no refresh token saved and no callback from the authorization server, 
        # then connect to the authorization server and request user consent.
        if (bingadsuser.refresh_token == ""):
            return redirect(authentication.get_authorization_endpoint())
    
        set_session_data(request, authentication)
    
        # At this point even if the user has valid Django web application credentials, 
        # we don't know whether they have access to Microsoft Advertising.
        # Let's test to see if they can call Bing Ads API service operations. 
    
        bing_ads_user = None
        accounts=[]
        errors=[]
    
        try:
            bing_ads_user = get_user(None)
            accounts = search_accounts_by_user_id(bing_ads_user.Id)['AdvertiserAccount']
        except WebFault as ex:
            errors=get_webfault_errors(ex)
            pass
    
        context = {
            'bingadsuser': bing_ads_user,
            'accounts': accounts,
            'errors': errors,
        }
        return render(
            request,
            'app/index.html',
            context
        )
    
    def revoke(request):
        """Deletes the refresh token for the user authenticated in the current session."""
        assert isinstance(request, HttpRequest)
    
        try:
            Users = get_user_model()
            user = User.objects.get(username=request.user.username)
            bingadsuser = user.bingadsuser
            if(bingadsuser is not None):
                bingadsuser.refresh_token = ""
                bingadsuser.save()
        except User.DoesNotExist:
            pass
        except BingAdsUser.DoesNotExist:
            pass
    
        clear_session_data(request)
    
        return render(
            request,
            'app/index.html'
        )
    
    def user_has_active_session(request):
        try:
            return True if request.session['is_authenticated'] else False 
        except KeyError:
            return False
    
    def user_has_refresh_token(username):
        try:
            Users = get_user_model()
            user = User.objects.get(username=username)
            bingadsuser = user.bingadsuser
            if(bingadsuser is not None and bingadsuser.refresh_token != ""):
                return True
        except User.DoesNotExist:
            return False
        except BingAdsUser.DoesNotExist:
            return False
    
    def set_session_data(request, authentication):
        global authorization_data
        global customer_service
    
        try:
            request.session['is_authenticated'] = True
    
            authorization_data.authentication = authentication
            authorization_data.developer_token = settings.DEVELOPER_TOKEN
    
            customer_service = ServiceClient(
                service='CustomerManagementService', 
                version=settings.API_VERSION,
                authorization_data=authorization_data,
                environment=settings.ENVIRONMENT
            )
    
        except KeyError:
            pass
        return None   
    
    def clear_session_data(request):
        global authorization_data
        global customer_service
    
        request.session['is_authenticated'] = False
    
        authorization_data = AuthorizationData(account_id=None, customer_id=None, developer_token=None, authentication=None)
        customer_service = None
    
    def applogout(request):
        logout(request)
        clear_session_data(request)
        return redirect('/')
    
    def get_user(user_id):
        ''' 
        Gets a Microsoft Advertising User object by the specified user ID.
    
        :param user_id: The Microsoft Advertising user identifier.
        :type user_id: long
        :return: The Microsoft Advertising user.
        :rtype: User
        '''
        global customer_service
    
        return customer_service.GetUser(UserId = user_id).User
    
    def search_accounts_by_user_id(user_id):
        ''' 
        Search for account details by UserId.
    
        :param user_id: The Microsoft Advertising user identifier.
        :type user_id: long
        :return: List of accounts that the user can manage.
        :rtype: Dictionary of AdvertiserAccount
        '''
    
        predicates={
            'Predicate': [
                {
                    'Field': 'UserId',
                    'Operator': 'Equals',
                    'Value': user_id,
                },
            ]
        }
    
        accounts=[]
    
        page_index = 0
        PAGE_SIZE=100
        found_last_page = False
    
        while (not found_last_page):
            paging=set_elements_to_none(customer_service.factory.create('ns5:Paging'))
            paging.Index=page_index
            paging.Size=PAGE_SIZE
            search_accounts_response = customer_service.SearchAccounts(
                PageInfo=paging,
                Predicates=predicates
            )
    
            if search_accounts_response is not None and hasattr(search_accounts_response, 'AdvertiserAccount'):
                accounts.extend(search_accounts_response['AdvertiserAccount'])
                found_last_page = PAGE_SIZE > len(search_accounts_response['AdvertiserAccount'])
                page_index += 1
            else:
                found_last_page=True
    
        return {
            'AdvertiserAccount': accounts
        }
    
    def set_elements_to_none(suds_object):
        for (element) in suds_object:
            suds_object.__setitem__(element[0], None)
        return suds_object
    
    def get_webfault_errors(ex):
        errors=[]
    
        if not hasattr(ex.fault, "detail"):
            raise Exception("Unknown WebFault")
    
        error_attribute_sets = (
            ["ApiFault", "OperationErrors", "OperationError"],
            ["AdApiFaultDetail", "Errors", "AdApiError"],
            ["ApiFaultDetail", "BatchErrors", "BatchError"],
            ["ApiFaultDetail", "OperationErrors", "OperationError"],
            ["EditorialApiFaultDetail", "BatchErrors", "BatchError"],
            ["EditorialApiFaultDetail", "EditorialErrors", "EditorialError"],
            ["EditorialApiFaultDetail", "OperationErrors", "OperationError"],
        )
    
        for error_attribute_set in error_attribute_sets:
            errors = get_api_errors(ex.fault.detail, error_attribute_set)
            if errors is not None:
                return errors
    
        return None
    
    def get_api_errors(error_detail, error_attribute_set):
        api_errors = error_detail
        for field in error_attribute_set:
            api_errors = getattr(api_errors, field, None)
        if api_errors is None:
            return None
    
        errors=[]
        if type(api_errors) == list:
            for api_error in api_errors:
                errors.append(api_error)
        else:
            errors.append(api_errors)
        return errors
    
  13. öğesinin içeriğini web_project/urls.py aşağıdaki içerikle değiştirin. Dosya urls.py , farklı URL'leri uygun görünümlere yönlendirmek için desenleri belirttiğiniz yerdir. Örneğin, aşağıdaki kod uygulamanın kök URL'sini ("") home yeni eklediğiniz işlevle app/views.pyeşler:

    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. Tüm değiştirilmiş dosyaları ile Ctrl+K Skaydedin.

  15. Veritabanını geçerli durumundan yeni duruma geçiren migrations klasöründe betikler oluşturmak için komutunu çalıştırın python manage.py makemigrations .

  16. Betikleri gerçek veritabanına uygulamak için komutunu çalıştırın python manage.py migrate . Geçiş betikleri, veri modellerinizde (models.py) zaman içinde yaptığınız tüm artımlı değişiklikleri etkili bir şekilde kaydeder. Django, geçişleri uygulayarak veritabanını modellerinizle eşleşecek şekilde güncelleştirir. Her artımlı değişikliğin kendi betiği olduğundan, Django otomatik olarak veritabanının önceki sürümlerini (yeni veritabanı dahil) geçerli sürüme geçirebilir. Sonuç olarak, yalnızca models.py modellerinizle ilgilenmeniz gerekir; hiçbir zaman temel alınan veritabanı şeması veya geçiş betikleriyle ilgilenmeniz gerekmez. Bu kısmı Django'ya bırak!

  17. Sanal ortamınız için VS Code'da bir Terminal açarak ve komutunu çalıştırarak python manage.py createsuperuser --username=<username> --email=<email><username><email>uygulamada bir süper kullanıcı hesabı oluşturun, ve öğesini elbette kişisel bilgilerinizle değiştirin. Komutunu çalıştırdığınızda, Django parolanızı girmenizi ve onaylamanızı ister.

    Önemli

    Kullanıcı adınızı ve parola bileşiminizi hatırlayacağınızdan emin olun. Bunlar, web uygulamasının yönetici portalında kimlik doğrulaması yapmak için kullandığınız kimlik bilgileridir.

  18. VS Code Terminali'nde, sanal ortam etkinleştirildiğinde geliştirme sunucusunu ile python manage.py runserver çalıştırın ve "Hello, Django" işleyen bir sayfayı görmek için http://127.0.0.1:8000/ bir tarayıcı açın.

  19. Web tarayıcısında adresine gidin http://127.0.0.1:8000/admin/ ve Kullanıcılar'ın altında yeni bir Django web kullanıcısı oluşturun. Bu, Microsoft Advertising kullanıcı kimlik bilgilerinizden farklıdır, böylece birden çok Microsoft Advertising kullanıcısı uygulamanızda ayrı olarak oturum açabilir.

    Django Yönetici

  20. Yeni kullanıcıyla (süper yöneticiyle değil) oturum açtığınızda bir Microsoft hesabıyla kimlik doğrulama seçeneğini görmeniz gerekir.

    Microsoft Hesabının Kimliğini Doğrulama Microsoft Hesabının

  21. Microsoft Hesabı Kimliğini Doğrula'ya tıkladıktan sonra, Microsoft Advertising hesaplarınızı yönetmek için kendi web uygulaması izinlerinizi vermeniz istenir. Onay verirseniz ve Microsoft Advertising hesaplarına erişiminiz varsa, hesap adınızın ve kimliklerinizin bir görünümüne yönlendirilmelisiniz.

Ayrıca Bkz

Bing Ads API'siyle Python Kullanmaya Başlama