Рубрики
Без рубрики

Создайте веб -сайт в социальных сетях с Django – бэкэнд приложения пользователей (часть 2)

Итак, в первой части учебника мы научились настроить наш проект и настроить различные аутентива … Tagged с Django, Python, WebDev, Programming.

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

Будет много терминов, с которыми вы можете столкнуться впервые, как вы, возможно, слышали о взглядах или моделях впервые, поэтому я буду немного бриффировать о них. Я не могу говорить о тех, кто в деталях, потому что наше внимание – не научить вас основным концепциям, а на создании веб -сайта в социальных сетях. Итак, я буду ссылаться на хорошие ресурсы для вас, чтобы ссылаться на эти конкретные темы, а затем продолжить этот урок.

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

models.py

В этом файле Python мы определим наши модели. Как вы уже знаете, модели определяются, чтобы рассказать Джанго, что сохранить в базе данных, и определить взаимосвязь между различными моделями и какими характеристиками у них есть.

Чтобы узнать больше о моделях Django, посетите это удивительное руководство по моделям по Разработчики Mozilla Анкет Он подробно рассказывает о моделях. После того, как вам станет комфортно, как работают модели, вы можете приступить к созданию моделей для нашего веб -сайта в социальных сетях.

Итак, у нас будет две модели – одна для профиля пользователя, а другая для запросов в друзья.

Нам нужно будет импортировать много вещей, прежде чем мы начнем писать модели. Мы будем использовать пользовательскую модель Django по умолчанию для того, чтобы иметь одно к одному отношению с нашей моделью профиля, то есть у каждого пользователя будет один профиль.

Мы также используем AutoSlug для автоматического производства слизняков для URL -адресов на основе имени пользователя.

Например: пользователь с именем, у Тома было бы Слог как Том. Это поможет нам создавать значимые URL -адреса, поскольку пользователи/Том приведут к профилю Тома, а не к числам.

Итак, чтобы использовать AutoSlug, нам нужно сначала установить его. Это можно сделать с помощью простой установки PIP. Ссылка ниже:

pip install django-autoslug

После его установки мы можем импортировать его в моделях.py, используя линию:

from autoslug import AutoSlugField

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

Итак, наша первая модель – модель профиля. У него пять параметров:-

  1. Пользователь – это отношение к одному к одному с пользовательской моделью Django. Каскад означает удаление пользователя, мы также разрушаем профиль.
  2. Изображение – это будет хранить изображение профиля пользователя. Мы также предоставили изображение по умолчанию. Нам нужно определить, где сохранить картинки.
  3. Слизняк – это будет место в слизне. Мы используем AutoSlugfield и будем устанавливать его, чтобы сделать слизняк из пользовательского поля.
  4. Биография – это будет хранить небольшое представление о пользователе. Здесь означает, что его можно оставить пустым.
  5. Друзья – это много во многих поля с моделью профиля и их можно оставить пустым. Это означает, что у каждого пользователя может быть несколько друзей и может быть друзьями для нескольких людей.

Далее мы описываем str который решает, как Джанго покажет нашу модель на панели администратора. Мы установили его, чтобы показать имя пользователя как объект запроса.

Мы также определяем get_absolute_url, чтобы получить абсолютный URL для этого профиля.

Далее мы определяем функцию для создания профиля, как только мы создаем пользователя, чтобы пользователю не приходилось вручную создавать профиль.

Далее мы определяем нашу модель друзей. У него будет три параметра:-

  1. TO_USER – Это обозначает пользователя, которому будет отправлен запрос в друзья. У него будет тот же параметр on_delete, который решает, когда пользователь удаляется, мы также удаляем запрос в друзья.
  2. from_user – это обозначает пользователя, который отправляет запрос в друзья. Он также будет удален, если пользователь будет удален.
  3. Временная метка – на самом деле не нужно добавлять. В нем хранится время, когда запрос был отправлен.

Как вы можете заметить, как TO_USER, так и From_user использует один и тот же Freeil -Key, поэтому, чтобы дифференцировать, нам нужно использовать поле avlective_name.

Итак, это заканчивает наш файл моделей.py. Посмотрите на приведенный ниже код, который показывает файл моделей.py.

from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils import timezone
from django.db.models.signals import post_save
from django.conf import settings
from autoslug import AutoSlugField

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.png', upload_to='profile_pics')
    slug = AutoSlugField(populate_from='user')
    bio = models.CharField(max_length=255, blank=True)
    friends = models.ManyToManyField("Profile", blank=True)

    def __str__(self):
        return str(self.user.username)

    def get_absolute_url(self):
        return "/users/{}".format(self.slug)

def post_save_user_model_receiver(sender, instance, created, *args, **kwargs):
    if created:
        try:
            Profile.objects.create(user=instance)
        except:
            pass

post_save.connect(post_save_user_model_receiver, sender=settings.AUTH_USER_MODEL)

class FriendRequest(models.Model):
    to_user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='to_user', on_delete=models.CASCADE)
    from_user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='from_user', on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return "From {}, to {}".format(self.from_user.username, self.to_user.username)

После моделей.

admin.py

Он будет коротким и будет состоять только из нескольких строк. Это обозначает модели, которые мы будем регистрировать на нашей панели администратора. Мы будем регистрировать обе наши модели здесь.

from django.contrib import admin
from .models import Profile, FriendRequest

admin.site.register(Profile)
admin.site.register(FriendRequest)

Далее мы переходим к Forms.py.

forms.py

Чтобы узнать больше о работе форм в Джанго, посетите этот официальный учебник самого Джанго. Затем перейдите в учебник.

Мы определяем три формы в нашем файле Forms.py.

  1. UserGregisterform – это для регистрации нового пользователя. Мы используем Django по умолчанию пользовательской формы и определяем, что должно быть в формах. Мы установили электронное письмо, чтобы быть почтовым полетом Джанго. Затем мы говорим Django, что модель – это пользователь и поля, которые мы попросили бы пользователя заполнить при регистрации.
  2. Userupdateform – эта форма позволит пользователям обновить свой профиль. Он будет иметь все те же поля, что и регистрационная форма, но мы будем использовать форму модели Django вместо пользовательского изменения.
  3. ProfileUpdateform – эта форма позволит пользователям обновить свой профиль.

Таким образом, добавление этих трех форм заполнит наш файл Forms.py. Посмотрите на код ниже:

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']


class UserUpdateForm(forms.ModelForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email']

class ProfileUpdateForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['bio', 'image']

Итак, после этого у нас создан файл forms.py. Далее мы увидим файл views.py.

views.py

Теперь мы определим файл views.py. Это будет содержать все наши представления (как рендерировать файлы в веб -браузере). Он напрямую передает данные в шаблоны.

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

  1. users_list – эта точка зрения сформирует список пользователей, который будет рекомендован любому пользователю, чтобы помочь им обнаружить новых пользователей, с которыми можно подружиться. Мы отфильтровываем наших друзей из этого списка и также исключим нас. Мы составим этот список, сначала добавив друзей нашего друга, которые не являются нашими друзьями. Затем, если в нашем списке пользователей все еще есть члены с низким уровнем, мы добавим случайных людей, которые рекомендуем (в основном для пользователя без друзей).
  2. FREEW_LIST – В этом представлении будут отображаться все друзья пользователя.
  3. send_friend_request – это поможет нам создать экземпляр запроса о дружбе и отправит запрос пользователю. Мы принимаем идентификатор пользователя, которому мы отправляем запрос, чтобы отправить ему запрос.
  4. cancel_friend_request – это отменит запрос на дружбу, который мы отправили пользователю.
  5. ACCECT_RIND_REQUEST – он будет использоваться для принятия запроса на друзья пользователя, и мы добавим пользователь1 в список друзей пользователя2 и наоборот. Кроме того, мы удалим запрос в друзья.
  6. delete_friend_request – это позволит пользователю удалить любой запрос в друзья, который он/она получил.
  7. delete_friend – Это удалит друга этого пользователя, то есть мы удалили пользователь1 из списка друзей 2 и наоборот.
  8. profile_view – это будет представление профиля любого пользователя. Это продемонстрирует количество друзей и подсчет сообщений пользователя и их списка друзей. Кроме того, он продемонстрировал бы запрос в друзья, полученный и отправленный пользователем и может принять, снизить или отменить запрос. Очевидно, что мы добавили бы условия и проверки, так что только заинтересованному пользователю показаны запросы и отправленный список, и у них есть только право принимать или отклонить запросы, а не кто -либо, кто просматривает его/ее профиль.
  9. Регистрация – это позволит пользователям зарегистрироваться на нашем веб -сайте. Это сделает регистрационную форму, которую мы создали в файле forms.py.
  10. редактировать профиль – Это позволит пользователям редактировать свой профиль с помощью форм, которые мы создали.
  11. search_users – это будет обрабатывать функцию поиска пользователей. Он принимает запрос, а затем отфильтровывает соответствующих пользователей.
  12. MY_PROFILE – это то же самое, что Profile_View, но он будет только ваш профиль.

Пройдите код ниже для лучшего понимания.

from django.shortcuts import render, redirect, get_object_or_404
from .models import Profile
from feed.models import Post
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth import get_user_model
from django.conf import settings
from django.http import HttpResponseRedirect
from .models import Profile, FriendRequest
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
import random

User = get_user_model()

@login_required
def users_list(request):
    users = Profile.objects.exclude(user=request.user)
    sent_friend_requests = FriendRequest.objects.filter(from_user=request.user)
    my_friends = request.user.profile.friends.all()
    sent_to = []
    friends = []
    for user in my_friends:
        friend = user.friends.all()
        for f in friend:
            if f in friends:
                friend = friend.exclude(user=f.user)
        friends += friend
    for i in my_friends:
        if i in friends:
            friends.remove(i)
    if request.user.profile in friends:
        friends.remove(request.user.profile)
    random_list = random.sample(list(users), min(len(list(users)), 10))
    for r in random_list:
        if r in friends:
            random_list.remove(r)
    friends += random_list
    for i in my_friends:
        if i in friends:
            friends.remove(i)
    for se in sent_friend_requests:
        sent_to.append(se.to_user)
    context = {
        'users': friends,
        'sent': sent_to
    }
    return render(request, "users/users_list.html", context)

def friend_list(request):
    p = request.user.profile
    friends = p.friends.all()
    context={
    'friends': friends
    }
    return render(request, "users/friend_list.html", context)

@login_required
def send_friend_request(request, id):
    user = get_object_or_404(User, id=id)
    frequest, created = FriendRequest.objects.get_or_create(
            from_user=request.user,
            to_user=user)
    return HttpResponseRedirect('/users/{}'.format(user.profile.slug))

@login_required
def cancel_friend_request(request, id):
    user = get_object_or_404(User, id=id)
    frequest = FriendRequest.objects.filter(
            from_user=request.user,
            to_user=user).first()
    frequest.delete()
    return HttpResponseRedirect('/users/{}'.format(user.profile.slug))

@login_required
def accept_friend_request(request, id):
    from_user = get_object_or_404(User, id=id)
    frequest = FriendRequest.objects.filter(from_user=from_user, to_user=request.user).first()
    user1 = frequest.to_user
    user2 = from_user
    user1.profile.friends.add(user2.profile)
    user2.profile.friends.add(user1.profile)
    if(FriendRequest.objects.filter(from_user=request.user, to_user=from_user).first()):
        request_rev = FriendRequest.objects.filter(from_user=request.user, to_user=from_user).first()
        request_rev.delete()
    frequest.delete()
    return HttpResponseRedirect('/users/{}'.format(request.user.profile.slug))

@login_required
def delete_friend_request(request, id):
    from_user = get_object_or_404(User, id=id)
    frequest = FriendRequest.objects.filter(from_user=from_user, to_user=request.user).first()
    frequest.delete()
    return HttpResponseRedirect('/users/{}'.format(request.user.profile.slug))

def delete_friend(request, id):
    user_profile = request.user.profile
    friend_profile = get_object_or_404(Profile, id=id)
    user_profile.friends.remove(friend_profile)
    friend_profile.friends.remove(user_profile)
    return HttpResponseRedirect('/users/{}'.format(friend_profile.slug))

@login_required
def profile_view(request, slug):
    p = Profile.objects.filter(slug=slug).first()
    u = p.user
    sent_friend_requests = FriendRequest.objects.filter(from_user=p.user)
    rec_friend_requests = FriendRequest.objects.filter(to_user=p.user)
    user_posts = Post.objects.filter(user_name=u)

    friends = p.friends.all()

    # is this user our friend
    button_status = 'none'
    if p not in request.user.profile.friends.all():
        button_status = 'not_friend'

        # if we have sent him a friend request
        if len(FriendRequest.objects.filter(
            from_user=request.user).filter(to_user=p.user)) == 1:
                button_status = 'friend_request_sent'

        # if we have recieved a friend request
        if len(FriendRequest.objects.filter(
            from_user=p.user).filter(to_user=request.user)) == 1:
                button_status = 'friend_request_received'

    context = {
        'u': u,
        'button_status': button_status,
        'friends_list': friends,
        'sent_friend_requests': sent_friend_requests,
        'rec_friend_requests': rec_friend_requests,
        'post_count': user_posts.count
    }

    return render(request, "users/profile.html", context)

def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Your account has been created! You can now login!')
            return redirect('login')
    else:
        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form':form})

@login_required
def edit_profile(request):
    if request.method == 'POST':
        u_form = UserUpdateForm(request.POST, instance=request.user)
        p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
        if u_form.is_valid() and p_form.is_valid():
            u_form.save()
            p_form.save()
            messages.success(request, f'Your account has been updated!')
            return redirect('my_profile')
    else:
        u_form = UserUpdateForm(instance=request.user)
        p_form = ProfileUpdateForm(instance=request.user.profile)
    context ={
        'u_form': u_form,
        'p_form': p_form,
    }
    return render(request, 'users/edit_profile.html', context)

@login_required
def my_profile(request):
    p = request.user.profile
    you = p.user
    sent_friend_requests = FriendRequest.objects.filter(from_user=you)
    rec_friend_requests = FriendRequest.objects.filter(to_user=you)
    user_posts = Post.objects.filter(user_name=you)
    friends = p.friends.all()

    # is this user our friend
    button_status = 'none'
    if p not in request.user.profile.friends.all():
        button_status = 'not_friend'

        # if we have sent him a friend request
        if len(FriendRequest.objects.filter(
            from_user=request.user).filter(to_user=you)) == 1:
                button_status = 'friend_request_sent'

        if len(FriendRequest.objects.filter(
            from_user=p.user).filter(to_user=request.user)) == 1:
                button_status = 'friend_request_received'

    context = {
        'u': you,
        'button_status': button_status,
        'friends_list': friends,
        'sent_friend_requests': sent_friend_requests,
        'rec_friend_requests': rec_friend_requests,
        'post_count': user_posts.count
    }

    return render(request, "users/profile.html", context)

@login_required
def search_users(request):
    query = request.GET.get('q')
    object_list = User.objects.filter(username__icontains=query)
    context ={
        'users': object_list
    }
    return render(request, "users/search_users.html", context)

Это подводит итог наше приложение пользователей. Мы остаемся с URLS.Py, который мы не включим в приложение пользователей. Мы добавим его непосредственно в наше приложение PhotoShare.

urls.py (PhotoShare)

Этот файл содержит все URL -адреса для веб -сайта. У него есть включение (‘feed.urls’), который включает в себя все URL -адреса из приложения Feed, которое мы построим в следующем учебном пособии.

И мы включаем все URL -адреса для приложения PhotoShare непосредственно в основной файл urls.py. Посмотрите на файл ниже:

from django.contrib import admin
from django.urls import path, include
from users import views as user_views
from django.contrib.auth import views as auth_views
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('feed.urls')),
    path('users/', user_views.users_list, name='users_list'),
    path('users//', user_views.profile_view, name='profile_view'),
    path('friends/', user_views.friend_list, name='friend_list'),
    path('users/friend-request/send//', user_views.send_friend_request, name='send_friend_request'),
    path('users/friend-request/cancel//', user_views.cancel_friend_request, name='cancel_friend_request'),
    path('users/friend-request/accept//', user_views.accept_friend_request, name='accept_friend_request'),
    path('users/friend-request/delete//', user_views.delete_friend_request, name='delete_friend_request'),
    path('users/friend/delete//', user_views.delete_friend, name='delete_friend'),
    path('edit-profile/', user_views.edit_profile, name='edit_profile'),
    path('my-profile/', user_views.my_profile, name='my_profile'),
    path('search_users/', user_views.search_users, name='search_users'),
    path('register/', user_views.register, name='register'),
    path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
    path('password-reset/', auth_views.PasswordResetView.as_view(template_name='users/password_reset.html'), name='password_reset'),
    path('password-reset/done/', auth_views.PasswordResetView.as_view(template_name='users/password_reset_done.html'), name='password_reset_done'),
    path('password-reset-confirm///', auth_views.PasswordResetConfirmView.as_view(template_name='users/password_reset_confirm.html'), name='password_reset_confirm'),
    path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view(template_name='users/password_reset_complete.html'), name='password_reset_complete'),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Оригинал: “https://dev.to/shubham1710/build-a-social-media-website-with-django-users-app-backend-part-2-2i4d”