Added Post, Profile, and Pagination features

This commit is contained in:
Rushil Umaretiya 2020-05-26 03:17:19 -04:00
parent 7a64a098c1
commit a106673ce6
40 changed files with 474 additions and 33 deletions

View File

@ -0,0 +1,17 @@
# Generated by Django 3.0.6 on 2020-05-26 03:31
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('blog', '0002_auto_20200430_0415'),
]
operations = [
migrations.RemoveField(
model_name='post',
name='title',
),
]

View File

@ -1,15 +1,18 @@
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.urls import reverse
# Create your models here. # Create your models here.
class Post(models.Model): class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField() content = models.TextField()
date_posted = models.DateTimeField(auto_now_add=True) date_posted = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User, on_delete=models.CASCADE) author = models.ForeignKey(User, on_delete=models.CASCADE)
likes = models.IntegerField(default=0) likes = models.IntegerField(default=0)
def __str__(self): def __str__(self):
return self.title return f"{self.author}'s post on {self.date_posted}"
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})

View File

@ -0,0 +1,3 @@
[ZoneTransfer]
ZoneId=3
ReferrerUrl=C:\Users\rushi\Downloads\segoe-ui-4-cufonfonts.zip

View File

@ -0,0 +1,3 @@
[ZoneTransfer]
ZoneId=3
ReferrerUrl=C:\Users\rushi\Downloads\segoe-ui-4-cufonfonts.zip

View File

@ -0,0 +1,3 @@
[ZoneTransfer]
ZoneId=3
ReferrerUrl=C:\Users\rushi\Downloads\segoe-ui-4-cufonfonts.zip

View File

@ -0,0 +1,3 @@
[ZoneTransfer]
ZoneId=3
ReferrerUrl=C:\Users\rushi\Downloads\segoe-ui-4-cufonfonts.zip

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3,11 +3,16 @@
src: url(futura.ttf); src: url(futura.ttf);
} }
@font-face {
font-family: 'Segoe UI';
src: url('Segoe UI.ttf');
}
body { body {
background: #fafafa; background: #fafafa;
color: #333333; color: #333333;
margin-top: 5rem; margin-top: 5rem;
font-family: Futura; font-family: 'Segoe UI';
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@ -21,7 +26,7 @@ ul {
.bg-steel { .bg-steel {
background: #5f788a; background: #5f788a;
background: linear-gradient(to right, #ec008c, #fc6767); background: linear-gradient(to right, #ec008c, #fc6767);
border-bottom: 3px #111 solid; /* border-bottom: 3px #111 solid; */
} }
.site-header .navbar-nav .nav-link { .site-header .navbar-nav .nav-link {
@ -90,3 +95,8 @@ a.article-title:hover {
.account-heading { .account-heading {
font-size: 2.5rem; font-size: 2.5rem;
} }
.nounderline {
text-decoration: none !important;
color: black !important;
}

View File

@ -35,7 +35,13 @@
</div> </div>
<!-- Navbar Right Side --> <!-- Navbar Right Side -->
<div class="navbar-nav"> <div class="navbar-nav">
{% if user.is_authenticated %}
<a class="nav-item nav-link" href="{% url 'post-create' %}">New Chirp</a>
<a class="nav-item nav-link" href="{% url 'profile' %}">{{ user.username }}</a>
<a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>
{% else %}
<a class="nav-item nav-link" href="{% url 'login' %}">Login</a> <a class="nav-item nav-link" href="{% url 'login' %}">Login</a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
@ -57,6 +63,19 @@
{% endif %} {% endif %}
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
<div class="col-md-4">
<div class="content-section">
<h3>Trending</h3>
<ul class="list-group">
<li class="list-group-item"><a href="https://www.djangoproject.com/">#Django</a></li>
<li class="list-group-item"><a href="https://tjctf.org">#TJCTF</a></li>
<li class="list-group-item"><a href="https://sysadmins.tjhsst.edu/understudy/">#Understudy</a></li>
<li class="list-group-item"><a href="https://dadjokegenerator.com/">#DadJokes</a></li>
</ul>
</p>
</div>
</div>
</div>
</div> </div>
</main> </main>

View File

@ -2,14 +2,35 @@
{% block content %} {% block content %}
{% for post in posts %} {% for post in posts %}
<article class="media content-section"> <article class="media content-section">
<img class="rounded-circle article-img" src="{{ post.author.profile.profile_pic.url}}" alt="Profile Picture">
<div class="media-body"> <div class="media-body">
<div class="article-metadata"> <div class="article-metadata">
<a class="mr-2" href="#">{{ post.author }}</a> <a class="mr-2" href="{% url 'user-posts' post.author.username %}">{{ post.author.get_full_name }}</a>
<small class="text-muted">{{ post.date_posted }}</small> <small class="text-muted">@{{ post.author }} · {{ post.date_posted }}</small>
</div> </div>
<h2><a class="article-title" href="#">{{ post.title }}</a></h2> <p class="article-content font-weight-light"><a class="nounderline" href="{% url 'post-detail' post.id %}">{{ post.content }}</a></p>
<p class="article-content">{{ post.content }}</p>
</div> </div>
</article> </article>
{% endfor %} {% endfor %}
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?page=1">First</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="?page={{ num }}">{{ num }}</a>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a class="btn btn-outline-info mb-4" href="?page={{ num }}">{{ num }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.next_page_number }}">Next</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.paginator.num_pages }}">Last</a>
{% endif %}
{% endif %}
{% endblock content %} {% endblock content %}

View File

@ -0,0 +1,27 @@
{% extends "blog/base.html" %}
{% block content %}
<div class="content-section">
<form method="post">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4"> Delete post </legend>
<h2>Are you sure you want to delete this post?</h2>
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ object.author.profile.profile_pic.url}}" alt="Profile Picture">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="#">{{ object.author.get_full_name }}</a>
<small class="text-muted">@{{ object.author }} · {{ object.date_posted }}</small>
</div>
<p class="article-content font-weight-light">{{ post.content }}</p>
</div>
</article>
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-outline-danger">Yes, Delete</button>
<a type="submit" class="btn btn-outline-secondary" href="{% url 'post-detail' object.id %}">No, take me back</a>
</div>
</form>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,19 @@
{% extends "blog/base.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ object.author.profile.profile_pic.url}}" alt="Profile Picture">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-posts' object.author.username %}">{{ object.author.get_full_name }}</a>
<small class="text-muted">@{{ object.author }} · {{ object.date_posted }}</small>
{% if object.author == user %}
<div>
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'post-update' object.id %}">Edit chirp</a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'post-delete' object.id %}">Delete chirp</a>
</div>
{% endif %}
</div>
<p class="article-content font-weight-light">{{ post.content }}</p>
</div>
</article>
{% endblock content %}

View File

@ -0,0 +1,16 @@
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="post">
{% csrf_token %}
<fieldset class="form-group">
{{ form | crispy}}
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-outline-info">Chirp</button>
</div>
</form>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,37 @@
{% extends "blog/base.html" %}
{% block content %}
<h1 class="mb-3">Posts by {{ view.kwargs.username }} ({{ page_obj.paginator.count }})</h1></h1>
{% for post in posts %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ post.author.profile.profile_pic.url}}" alt="Profile Picture">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-posts' post.author.username %}">{{ post.author.get_full_name }}</a>
<small class="text-muted">@{{ post.author }} · {{ post.date_posted }}</small>
</div>
<p class="article-content font-weight-light"><a class="nounderline" href="{% url 'post-detail' post.id %}">{{ post.content }}</a></p>
</div>
</article>
{% endfor %}
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?page=1">First</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="?page={{ num }}">{{ num }}</a>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a class="btn btn-outline-info mb-4" href="?page={{ num }}">{{ num }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.next_page_number }}">Next</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.paginator.num_pages }}">Last</a>
{% endif %}
{% endif %}
{% endblock content %}

View File

@ -1,7 +1,23 @@
from django.urls import path from django.urls import path
from .views import (
PostListView,
PostDetailView,
PostCreateView,
PostUpdateView,
PostDeleteView,
UserPostListView,
)
from . import views from . import views
urlpatterns = [ urlpatterns = [
path('', views.home, name='blog-home'), path('', PostListView.as_view(), name='blog-home'),
path('user/<str:username>', UserPostListView.as_view(), name='user-posts'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
path('post/new/', PostCreateView.as_view(), name='post-create'),
path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
path('about/', views.about, name='blog-about'), path('about/', views.about, name='blog-about'),
] ]

View File

@ -1,4 +1,13 @@
from django.shortcuts import render from django.shortcuts import render, get_object_or_404
from django.contrib.auth.models import User
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic import (
ListView,
DetailView,
CreateView,
UpdateView,
DeleteView,
)
from .models import Post from .models import Post
def home (request): def home (request):
@ -7,5 +16,53 @@ def home (request):
} }
return render(request, 'blog/home.html', context) return render(request, 'blog/home.html', context)
class PostListView(ListView):
model = Post
template_name = "blog/home.html"
context_object_name='posts'
ordering = ['-date_posted']
paginate_by = 8
class UserPostListView(ListView):
model = Post
template_name = "blog/user_posts.html"
context_object_name='posts'
paginate_by = 8
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-date_posted')
class PostDetailView(DetailView):
model = Post
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields=['content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Post
fields=['content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
return self.request.user == post.author
class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Post
success_url='/'
def test_func(self):
post = self.get_object()
return self.request.user == post.author
def about (request): def about (request):
return render(request, 'blog/about.html', {'title': 'About'}) return render(request, 'blog/about.html', {'title': 'About'})

View File

@ -46,6 +46,7 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'crispy_forms',
'oauth2_provider', 'oauth2_provider',
'corsheaders', 'corsheaders',
] ]
@ -131,3 +132,11 @@ USE_TZ = True
# https://docs.djangoproject.com/en/3.0/howto/static-files/ # https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/' STATIC_URL = '/static/'
CRISPY_TEMPLATE_PACK = 'bootstrap4'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
LOGIN_REDIRECT_URL = 'blog-home'
LOGIN_URL = 'login'

View File

@ -13,6 +13,8 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path 1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from users import views as user_views from users import views as user_views
@ -20,6 +22,12 @@ from users import views as user_views
urlpatterns = [ urlpatterns = [
path('', include('blog.urls')), path('', include('blog.urls')),
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('login/', include('users.urls')), path('login/', user_views.login, name='login'),
path('logout/', user_views.logout, name='logout'),
path('callback/', user_views.callback),
path('profile/', user_views.profile, name='profile'),
path("o/", include('oauth2_provider.urls', namespace='oauth2_provider')), path("o/", include('oauth2_provider.urls', namespace='oauth2_provider')),
] ]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

0
chirper/manage.py Executable file → Normal file
View File

BIN
chirper/media/default.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
chirper/media/default2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

View File

@ -1,3 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import Profile
# Register your models here. # Register your models here.
admin.site.register(Profile)

View File

@ -3,3 +3,6 @@ from django.apps import AppConfig
class UsersConfig(AppConfig): class UsersConfig(AppConfig):
name = 'users' name = 'users'
def ready(self):
import users.signals

22
chirper/users/forms.py Normal file
View File

@ -0,0 +1,22 @@
from django import forms
from django.contrib.auth.models import User
from .models import Profile
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
def __init__(self, *args, **kwargs):
super(UserUpdateForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['username'].widget.attrs['readonly'] = True
class Meta:
model = User
fields = ['username', 'email']
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['profile_pic']

View File

@ -0,0 +1,25 @@
# Generated by Django 3.0.6 on 2020-05-26 03:31
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('profile_pic', models.ImageField(default='default.jpg', upload_to='profile.pics')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.6 on 2020-05-26 03:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='profile_pic',
field=models.ImageField(default='default.jpg', upload_to='profile_pics'),
),
]

View File

@ -1,3 +1,22 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User
from PIL import Image
# Create your models here. # Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__ (self):
return f"{self.user.username}'s Profile"
def save(self):
super().save()
img = Image.open(self.profile_pic.path)
if img.height > 300 or img.width > 300:
size = (300, 300)
img.thumbnail(size)
img.save(self.profile_pic.path)

13
chirper/users/signals.py Normal file
View File

@ -0,0 +1,13 @@
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()

View File

@ -1,6 +1,9 @@
{% extends "blog/base.html" %} {% extends "blog/base.html" %}
{% block content %} {% block content %}
<div class="content-section"> <div class="content-section">
<a class="btn btn-primary btn-lg btn-block" href="{{authorization_url}}">Sign in with Ion</a> <a href="{{ authorization_url }}" title="Ion" class="border border-dark p-3 btn btn-block btn-lg mx-auto">
</div> <img src="https://ion.tjhsst.edu/static/img/favicon.png">
Sign in with Ion
</a>
</div>
{% endblock content %} {% endblock content %}

View File

@ -0,0 +1,9 @@
{% extends "blog/base.html" %}
{% block content %}
<h2>You have been logged out</h2>
<div class="border-top pt-2">
<small class="text-muted text-large">
<a href="{% url 'login' %}">Log In Again</a>
</small>
</div>
{% endblock content %}

View File

@ -0,0 +1,25 @@
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ user.profile.profile_pic.url }}">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">{{ user.email }}</p>
</div>
</div>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4"> Your profile </legend>
{{ userForm|crispy}}
{{ profileForm|crispy }}
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-outline-info">Update</button>
</div>
</form>
</div>
</div>
{% endblock content %}

View File

@ -1,7 +0,0 @@
from django.urls import path
from . import views
urlpatterns = [
path('', views.login, name='login'),
path('callback/', views.callback)
]

View File

@ -1,19 +1,28 @@
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.contrib.auth import login as auth_login
from django.contrib import messages
from requests_oauthlib import OAuth2Session
import json import json
import requests import requests
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from requests_oauthlib import OAuth2Session
from django.contrib import messages
from .forms import UserUpdateForm, ProfileUpdateForm
# Create your views here. # Create your views here.
client_id = r'6p7HJlFCD8cnBNBEdgMsdULS5ph0jserw1xvWfxX' client_id = r'6p7HJlFCD8cnBNBEdgMsdULS5ph0jserw1xvWfxX'
client_secret = r'E1e79KebxzAp0LBEtxcUg32b0qFP9Ap9Dxqkac6Qhci5AwXFhSfrbe7MtmGJUh6DDgxivJpGgFYNQgusfvoSraDAnsq3NnEET5DmxgfBBvvuYc2bwDq6KpeKIDQqFtwz' client_secret = r'E1e79KebxzAp0LBEtxcUg32b0qFP9Ap9Dxqkac6Qhci5AwXFhSfrbe7MtmGJUh6DDgxivJpGgFYNQgusfvoSraDAnsq3NnEET5DmxgfBBvvuYc2bwDq6KpeKIDQqFtwz'
redirect_uri = 'http://localhost:8000/login/callback/' redirect_uri = 'http://localhost:8000/callback/'
token_url = 'https://ion.tjhsst.edu/oauth/authorize/' token_url = 'https://ion.tjhsst.edu/oauth/authorize/'
scope=["read","write"] scope=["read"]
authorized_users=["2023rumareti", "Your ION_USERNAME"] authorized_users=["2023rumareti", "Your ION_USERNAME"]
# Hey that's me # Hey that's me
@ -59,11 +68,40 @@ def callback (request):
user = User.objects.create_user(username=username, email=email, password=username, first_name=first_name, last_name=last_name) user = User.objects.create_user(username=username, email=email, password=username, first_name=first_name, last_name=last_name)
user.save() user.save()
auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend')
messages.success(request, f"Welcome to Chirper, {first_name}, we hope you like your stay!") messages.success(request, f"Welcome to Chirper, {first_name}, we hope you enjoy your stay!")
return redirect('/') return redirect('profile')
else: else:
messages.error(request, "Sorry, you're not an authorized Ion user!", extra_tags='danger') messages.error(request, "Sorry, you're not an authorized Ion user!", extra_tags='danger')
return redirect('/') return redirect('blog-home')
messages.warning(request, "Invalid Callback Response") messages.warning(request, "Invalid Callback Response")
return redirect('/') return redirect('blog-home')
@login_required
def logout(request):
auth_logout(request)
return render(request, 'users/logout.html')
@login_required
def profile(request):
if request.method == "POST":
userForm = UserUpdateForm(request.POST, instance=request.user)
profileForm = ProfileUpdateForm(request.POST,
request.FILES,
instance=request.user.profile)
if userForm.is_valid() and profileForm.is_valid():
userForm.save()
profileForm.save()
messages.success(request, "Your account has been updated!")
return redirect('profile')
else:
userForm = UserUpdateForm(instance=request.user)
profileForm = ProfileUpdateForm(instance=request.user.profile)
context = {
'userForm': userForm,
'profileForm': profileForm
}
return render(request, 'users/profile.html', context)