Российский Новый Университет
Опубликован: 25.01.2016 | Доступ: свободный | Студентов: 2234 / 161 | Длительность: 16:40:00
Лекция 7:

Чтение и комментирование

< Лекция 6 || Лекция 7: 123 || Лекция 8 >

Модели входа пользователя

Для осуществления входа пользователя в систему, мы должны добавить URL-адреса по умолчанию для входа и регистрации. Мы будем добавлять следующие шаблоны URL-адресов в файл urls.py:

url(r'^login/$', 'django.contrib.auth.views.login'),
url(r'^logout/$', 'django.contrib.auth.views.logout'),

Теперь наш файл urls.py выглядит следующим образом:

from django.conf.urls import patterns, include, url

from django.contrib import admin

from tweet.views import Index, Profile, PostTweet, HashTagCloud, Search, SearchHashTag, HashTagJson 

admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', Index.as_view()),
    url(r'^user/(\w+)/$', Profile.as_view()),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^user/(\w+)/post/$', PostTweet.as_view()),
    url(r'^hashTag/(\w+)/$', HashTagCloud.as_view()),
    url(r'^search/$', Search.as_view()),
    url(r'^search/hashTag$',SearchHashTag.as_view())),
    url(r'^hashtag.json$', HashTagJson.as_view()),
    url(r'^login/$', 'django.contrib.auth.views.login'),
    url(r'^logout/$', 'django.contrib.auth.views.logout'),
)

У представлений входа в систему и выхода из нее имена шаблонов по умолчанию, registration/login.html и registration/login_out.html соответственно. Поскольку эти представления специфичны для пользователя и не очень специфичны для повторного использования нашего приложения, мы создадим новый каталог шаблона/регистрации внутри проекта mytweets, используя следующую команду:

mkdir –p mytweets/templates/registration

Затем создадим простые страницы входа в систему и выхода из нее. Оформим следующий фрагмент кода в файл login.html.

{% extends "base.html" %}

{% block content %}

    {% if form.errors %}
        <p> Ваши логин и пароль не совпадают. Попробуйте еще. </p>
    {% endif %}

    <form method="post" action="{% url 'django.contrib.auth.views.login' %}">
        {% csrf_token %}
        <table>
            <tr>
                <td>{{ form.username.label_tag }}</td>
                <td>{{ form.username }}</td>
            </tr>
            <tr>
                <td>{{ form.password.label_tag }}</td>
                <td>{{ form.password }}</td>
            </tr>
        </table>

        <input type="submit" value="login"/>
        <input type="hidden" name="next" value="{{ next }}"/>
    </form>

{% endblock %}

Оформим следующий фрагмент кода в файл logout.html:

{% extends "base.html" %}

{% block content %}
Вы вышли из системы!
{% endblock %}

Мы просто активируем систему аутентификации Django по умолчанию. Так как это базовая аутентификация, то требуется предопределить URL для правильного перенаправления. Например мы уже знаем, что что /login принимает пользователя от html-страницы /registration/login. Аналогично, после того, как пользователь прошел проверку подлинности, перенаправляются на URL accounts/profile. В нашем проекте у нас есть пользовательские URL для каждого пользователя. Мы обновим эти записи в файле settings.py:

LOGIN_REDIRECT_URL = '/profile'
LOGIN_URL = 'django.contrib.auth.views.login'

Для сохранения простоты, мы просто создаем представление, которое будет забирать пользователя, прошедшего аутентификацию из профиля и перенаправляющего этого пользователя на страницу его профиля. Главным образом, мы создаем параметр имени пользователя после его аутентификации. Иными словами, /profile | /profile/<username> генерируется в отдельное представление класса. Для этого нам нужно создать нижеследующую URL-запись:

url(r'^profile/$', UserRedirect.as_view()),

А перенаправляющий класс Profile с методом get() будет выглядеть как:

class UserRedirect(View):
    def get(self, request):
    return HttpResponseRedirect('/user/'+request.user.username)

Вот так. Теперь каждый пользователь, входящий в систему пользователь будет перенаправляться на его страницу профиля.

Теперь возвращаясь к исходной задаче, когда пользователь посещает профиль другого пользователя, у него должна быть возможность чтения профиля пользователя; это означает, что читатель будет получать обновления о всех опубликованных твитах на своей домашней странице.

После того, как пользователь начал читать, у него появляется возможность перестать читать, а если пользователь посетил свой собственный профиль, он не должен увидеть никаких вариантов.

Обновленный код для профиля пользователя выглядит следующим образом:

{% extends "base.html" %}
{% load staticfiles %}
{% block navbar %}
     <p class="navbar-text navbar-left">
        <span class="glyphicon glyphicon-user"> </span>  {{ profile.username }}'s Profile Page
         {% if profile.username != user.username %}
              <span class="btn btn-xs btn-default follow-btn" title="Click to follow {{ profile.username }}" value="{{ following }}" username="{{ profile.username }}">
             <span class="glyphicon glyphicon-plus"></span><span class="follow-text">
                 {{ following|yesno:"Unfollow,Follow" }}
             </span></span>
         {% endif %}
    </p>
    <p class="navbar-text navbar-right">
        <span class="glyphicon glyphicon-user"></span> {{ user.username }}
    </p>
{% endblock %}
{% block content %}

    <div class="row clearfix">
        <div class="col-md-6 col-md-offset-3 column">
            <form id="search-form" action="post/" method="POST">{% csrf_token %}
                <div class="input-group">
                    {{ form.text.errors }}
                    {{ form.text }}
                    {{ form.country.as_hidden }}

      <span class="input-group-btn">
        <button class="btn btn-default" type="submit">Post</button>
      </span>
                </div>
                <!-- /input-group -->
            </form>
        </div>

        <h1> </h1>

        <div class="col-md-12 column">
            {% for tweet in tweets %}
                <div class="well">
                    <span>{{ tweet.text }}</span>
                </div>
            {% endfor %}
        </div>
    </div>
{% endblock %}

Следующий код проверяет, просматривает ли пользователь свой собственный профиль; Если это так, кнопка чтения не отображается. Он также проверяет находится ли пользователь вошедший в систему в профиле пользователя, который тот читает; если это так, будет показана кнопка прекращения чтения, а если нет, будет показана кнопка чтения.

{% if profile.username != user.username %}
              <span class="btn btn-xs btn-default follow-btn" title="Click to follow {{ profile.username }}" value="{{ following }}" username="{{ profile.username }}">
             <span class="glyphicon glyphicon-plus"></span><span class="follow-text">
                 {{ following|yesno:"Unfollow,Follow" }}
             </span></span>
         {% endif %}

Для отрисовки обновленного содержимого, обновим класс Profile() соответственно:

class Profile(LoginRequiredMixin, View):
    """User Profile page reachable from /user/<username> URL"""
    def get(self, request, username):
        params = dict()
        userProfile = User.objects.get(username=username)
            userFollower = UserFollower.objects.get(user=userProfile)
            if userFollower.followers.filter(username=request.user.username).exists():
                params["following"] = True
            else:
                params["following"] = False
        except:
            userFollower = []

        form = TweetForm(initial={'country': 'Global'})
        search_form = SearchForm()
        tweets = Tweet.objects.filter(user=userProfile).order_by('-created_date')
        params["tweets"] = tweets
        params["profile"] = userProfile
        params["form"] = form
        params["search"] = search_form
        return render(request, 'profile.html', params)

Следующий код проверяет, является ли пользователь, вошедший в систему, читателем пользователя, страницу которого он посетил:

if userFollower.followers.filter
(username=request.user.username).exists()
< Лекция 6 || Лекция 7: 123 || Лекция 8 >
Константин Боталов
Константин Боталов

Вроде легкие вопросы и ответы знаю правильные, но система считает иначе и правильные ответысчитает неправильными. Приходится выполнть по несколько раз. Это я не правильно делаю или тест так составлен?

Владимир Филипенко
Владимир Филипенко

Листинг показывает в 4-ой лекции, что установлен Django 1.8.4. Тут же далее в этой лекции указаны настройки, которые воспринимает Django 1.7 и младше.