--- tags: Python Web source: Django 2.0 для начинающих, Глава 10, с.210 --- # Тема 8. Bootstrap https://github.com/roman-yatsenko/django-topics/tree/main/news ## Приложение Pages ```shell python manage.py startapp pages ``` ### `news_project\settings.py` ```python=33 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'users', 'pages' # new ] ``` ### `news_project\urls.py` ```python=16 from django.contrib import admin from django.urls import path, include # delete next import urlpatterns = [ path('', include('pages.urls')), # change path('admin/', admin.site.urls), path('users/', include('users.urls')), path('users/', include('django.contrib.auth.urls')), ] ``` ```shell touch pages/urls.py ``` ### `pages\urls.py` ```python= from django.urls import path from . import views urlpatterns = [ path('', views.HomePageView.as_view(), name='home'), ] ``` ### `pages\views.py` ```python= from django.views.generic import TemplateView class HomePageView(TemplateView): template_name = 'home.html' ``` ```shell python manage.py runserver ``` ## Тесты ### `pages\tests.py` ```python= from django.contrib.auth import get_user_model from django.test import SimpleTestCase, TestCase from django.urls import reverse class HomePageTests(SimpleTestCase): def test_home_page_status_code(self): response = self.client.get('/') self.assertEqual(response.status_code, 200) def test_view_url_by_name(self): response = self.client.get(reverse('home')) self.assertEqual(response.status_code, 200) def test_view_uses_correct_template(self): response = self.client.get(reverse('home')) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'home.html') class SignupPageTests(TestCase): username = 'newuser' email = 'newuser@email.com' def test_signup_page_status_code(self): response = self.client.get('/users/signup/') self.assertEqual(response.status_code, 200) def test_view_url_by_name(self): response = self.client.get(reverse('signup')) self.assertEqual(response.status_code, 200) def test_view_uses_correct_template(self): response = self.client.get(reverse('signup')) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'signup.html') def test_signup_form(self): new_user = get_user_model().objects.create_user(self.username, self.email) self.assertEqual(get_user_model().objects.all().count(), 1) self.assertEqual(get_user_model().objects.all()[0].username, self.username) self.assertEqual(get_user_model().objects.all()[0].email, self.email) ``` ```shell python manage.py test ``` ## Bootstrap https://getbootstrap.com/docs/4.6/getting-started/introduction/ ### `templates\base.html` ```htmlmixed= <!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous"> <title>Newspaper App</title> </head> <body> {% block content %} {% endblock %} <!-- Optional JavaScript; choose one of the two! --> <!-- Option 1: jQuery and Bootstrap Bundle (includes Popper) --> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script> </body> </html> ``` ```shell= python manage.py runserver ``` ## NavBar https://getbootstrap.com/docs/4.6/components/navbar/#supported-content ### `templates\base.html` ```htmlmixed=13 <body> <nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4"> <a class="navbar-brand" href="{% url 'home' %}">Newspaper</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> {% if user.is_authenticated%} <ul class="navbar-nav ml-auto"> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> {{ user.username }} </a> <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="{% url 'password_change' %}">Change password</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="{% url 'logout' %}">Log out</a> </div> </li> </ul> {% else %} <form class="form-inline ml-auto"> <a class="btn btn-outline-secondary" href="{% url 'login' %}">Log in</a> <a class="btn btn-primary ml-2" href="{% url 'signup' %}">Sign Up</a> </form> {% endif %} </div> </nav> <div class="container"> {% block content %} {% endblock %} </div> ``` ### `templates\registration\login.html` ```htmlmixed=10 <button class="btn btn-success ml-2" type="submit">Login</button> ``` ## Signup Form ```shell pipenv install django-crispy-forms ``` ### `news_project\settings.py` ```python=33 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # 3rd Party 'crispy_forms', # Local 'users', 'pages', ] ``` ```python=135 CRISPY_TEMPLATE_PACK = 'bootstrap4' ``` ### `templates\signup.html` ```htmlmixed= {% extends 'base.html' %} {% load crispy_forms_tags %} {% block title %}Sign Up{% endblock %} {% block content %} <h2>Sign up</h2> <form method="post"> {% csrf_token %} {{ form|crispy }} <button class="btn btn-success" type="submit">Sign up</button> </form> {% endblock %} ``` ```shell= python manage.py runserver ``` --- (c) Яценко Р.Н., 2021 [Учебный центр компьютерных технологий "Кит"](http://kit.kh.ua/) <img src="https://i.imgur.com/Kh901c1.png" style="width: 150px; position: fixed; top: 100px; right: 10px; border: 0; box-shadow: none;">