added more fields to article so that it's more of an article object

This commit is contained in:
Rushil Umaretiya 2020-08-15 11:38:14 -04:00
parent 2129f28909
commit 2d92621026
17 changed files with 155 additions and 19 deletions

BIN
media/default-header.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
media/profile_pics/uhuh.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1 on 2020-08-15 14:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('news', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='article',
name='header',
field=models.ImageField(default='default.jpg', upload_to='article-headers'),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 3.1 on 2020-08-15 15:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('news', '0002_article_header'),
]
operations = [
migrations.AddField(
model_name='article',
name='header_caption',
field=models.TextField(default=''),
),
migrations.AlterField(
model_name='article',
name='header',
field=models.ImageField(default='default-header.jpg', upload_to='article-headers'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.1 on 2020-08-15 15:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('news', '0003_auto_20200815_1130'),
]
operations = [
migrations.AddField(
model_name='article',
name='headline',
field=models.TextField(default='Headline'),
preserve_default=False,
),
]

View File

@ -4,16 +4,31 @@ from django.utils import timezone
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.urls import reverse from django.urls import reverse
from PIL import Image
# Create your models here. # Create your models here.
class Article(models.Model): class Article(models.Model):
headline = models.TextField()
content = models.TextField() content = models.TextField()
date_published = models.DateTimeField(auto_now_add=True) date_published = 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)
header = models.ImageField(default='default-header.jpg', upload_to='article-headers')
header_caption = models.TextField(default="")
def __str__(self): def __str__(self):
return f"{self.author}'s article on {self.date_published}" return f"{self.author}'s article on {self.date_published}"
def get_absolute_url(self): def get_absolute_url(self):
return reverse('article-detail', kwargs={'pk': self.pk}) return reverse('article-detail', kwargs={'pk': self.pk})
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.header.path)
if img.width > 1280 or img.height > 768:
output_size = (1280, 768)
img.thumbnail(output_size)
img.save(self.header.path)

View File

@ -1,4 +1,4 @@
{% extends 'news/base.html' %} {% extends 'news/base.html' %}
{% block content %} {% block content %}
<h1>home</h1> <h1>This is the NVN about page.</h1>
{% endblock content %} {% endblock content %}

View File

@ -6,6 +6,7 @@
<div class="article-metadata"> <div class="article-metadata">
<a class="mr-2" href="{% url 'user-articles' object.author.username %}">{{ object.author.get_full_name }}</a> <a class="mr-2" href="{% url 'user-articles' object.author.username %}">{{ object.author.get_full_name }}</a>
<small class="text-muted">@{{ object.author }} · {{ object.date_published }}</small> <small class="text-muted">@{{ object.author }} · {{ object.date_published }}</small>
{% if object.author == user %} {% if object.author == user %}
<div> <div>
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'article-update' object.id %}">Edit article</a> <a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'article-update' object.id %}">Edit article</a>
@ -13,6 +14,8 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
<img class="" src="{{ object.header.url }}">
<p class="article-content font-weight-light">{{ article.content }}</p> <p class="article-content font-weight-light">{{ article.content }}</p>
</div> </div>
</article> </article>

View File

@ -40,6 +40,7 @@
<a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a> <a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>
{% else %} {% else %}
<a class="nav-item nav-link" href="{% url 'login' %}">Login</a> <a class="nav-item nav-link" href="{% url 'login' %}">Login</a>
<a class="nav-item nav-link" href="{% url 'register' %}">Register</a>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -6,9 +6,9 @@
<div class="media-body"> <div class="media-body">
<div class="article-metadata"> <div class="article-metadata">
<a class="mr-2" href="{% url 'user-articles' article.author.username %}">{{ article.author.get_full_name }}</a> <a class="mr-2" href="{% url 'user-articles' article.author.username %}">{{ article.author.get_full_name }}</a>
<small class="text-muted">@{{ article.author }} · {{ article.date_published }}</small> <a href="{% url 'user-articles' article.author.username %}"><small class="text-muted">@{{ article.author }} · {{ article.date_published }}</small></a>
</div> </div>
<p class="article-content font-weight-light"><a class="nounderline" href="{% url 'article-detail' article.id %}">{{ article.content }}</a></p> <p class="article-content font-weight-light"><a class="nounderline" href="{% url 'article-detail' article.id %}">{{ article.headline }}</a></p>
</div> </div>
</article> </article>
{% endfor %} {% endfor %}

View File

@ -16,11 +16,12 @@ from users.models import Profile
# Create your views here. # Create your views here.
def about (request): def about (request):
createProfileIfNotExist(request)
return render (request, 'news/about.html') return render (request, 'news/about.html')
def home (request): def home (request):
if request.user.is_authenticated and Profile.objects.filter(user=request.user).count() < 1: createProfileIfNotExist(request)
Profile.objects.create(user=request.user).save()
context = { context = {
'articles': Article.objects.all() 'articles': Article.objects.all()
@ -29,6 +30,7 @@ def home (request):
return render (request, 'news/home.html', context) return render (request, 'news/home.html', context)
class ArticleListView(ListView): class ArticleListView(ListView):
model = Article model = Article
template_name = "news/home.html" template_name = "news/home.html"
context_object_name='articles' context_object_name='articles'
@ -50,7 +52,7 @@ class ArticleDetailView(DetailView):
class ArticleCreateView(LoginRequiredMixin, CreateView): class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article model = Article
fields=['content'] fields=['headline','header','header_caption','content']
def form_valid(self, form): def form_valid(self, form):
form.instance.author = self.request.user form.instance.author = self.request.user
@ -58,7 +60,7 @@ class ArticleCreateView(LoginRequiredMixin, CreateView):
class ArticleUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView): class ArticleUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Article model = Article
fields=['content'] fields=['headline','header','header_caption','content']
def form_valid(self, form): def form_valid(self, form):
form.instance.author = self.request.user form.instance.author = self.request.user
@ -75,3 +77,7 @@ class ArticleDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
def test_func(self): def test_func(self):
article = self.get_object() article = self.get_object()
return self.request.user == article.author return self.request.user == article.author
def createProfileIfNotExist (request):
if request.user.is_authenticated and Profile.objects.filter(user=request.user).count() < 1:
Profile.objects.create(user=request.user).save()

View File

@ -17,7 +17,7 @@ class UserUpdateForm(forms.ModelForm):
class Meta: class Meta:
model = User model = User
fields = ['username', 'email'] fields = ['username', 'email', 'first_name', 'last_name']
class ProfileUpdateForm(forms.ModelForm): class ProfileUpdateForm(forms.ModelForm):

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1 on 2020-08-15 15:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0003_auto_20200815_0302'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='profile_pic',
field=models.ImageField(default='default-pfp.jpg', upload_to='profile_pics'),
),
]

View File

@ -1,5 +1,3 @@
from django.db import models
# Create your models here. # Create your models here.
from django.db import models from django.db import models
@ -9,7 +7,7 @@ from PIL import Image
class Profile(models.Model): class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE) user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(default='default.jpg', upload_to='profile_pics') profile_pic = models.ImageField(default='default-pfp.jpg', upload_to='profile_pics')
def __str__(self): def __str__(self):
return f'{self.user.username} Profile' return f'{self.user.username} Profile'

View File

@ -6,11 +6,12 @@
<img class="rounded-circle account-img" src="{{ user.profile.profile_pic.url }}"> <img class="rounded-circle account-img" src="{{ user.profile.profile_pic.url }}">
<div class="media-body"> <div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2> <h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">{{ user.first_name }} {{ user.last_name }}</p>
<p class="text-secondary">{{ user.email }}</p> <p class="text-secondary">{{ user.email }}</p>
</div> </div>
</div> </div>
<hr>
<h2>Settings</h2> <h2>Social Settings</h2>
<h3>GitHub</h3> <h3>GitHub</h3>
{% if github_login %} {% if github_login %}
@ -18,7 +19,7 @@
{% if can_disconnect %} {% if can_disconnect %}
<form method="post" action="{% url 'social:disconnect' 'github' %}"> <form method="post" action="{% url 'social:disconnect' 'github' %}">
{% csrf_token %} {% csrf_token %}
<button type="submit">Disconnect from GitHub</button> <button type="submit" class="btn btn-outline-info">Disconnect from GitHub</button>
</form> </form>
{% else %} {% else %}
<button type="button" disabled>Disconnect from GitHub</button> <button type="button" disabled>Disconnect from GitHub</button>
@ -34,7 +35,7 @@
{% if can_disconnect %} {% if can_disconnect %}
<form method="post" action="{% url 'social:disconnect' 'google-oauth2' %}"> <form method="post" action="{% url 'social:disconnect' 'google-oauth2' %}">
{% csrf_token %} {% csrf_token %}
<button type="submit">Disconnect from Google</button> <button type="submit" class="btn btn-outline-info">Disconnect from Google</button>
</form> </form>
{% else %} {% else %}
<button type="button" disabled>Disconnect from Google</button> <button type="button" disabled>Disconnect from Google</button>
@ -50,7 +51,7 @@
{% if can_disconnect %} {% if can_disconnect %}
<form method="post" action="{% url 'social:disconnect' 'facebook' %}"> <form method="post" action="{% url 'social:disconnect' 'facebook' %}">
{% csrf_token %} {% csrf_token %}
<button type="submit">Disconnect from Facebook</button> <button type="submit" class="btn btn-outline-info">Disconnect from Facebook</button>
</form> </form>
{% else %} {% else %}
<button type="button" disabled>Disconnect from Facebook</button> <button type="button" disabled>Disconnect from Facebook</button>
@ -60,6 +61,7 @@
<a href="{% url 'social:begin' 'facebook' %}">Connect to Facebook</a> <a href="{% url 'social:begin' 'facebook' %}">Connect to Facebook</a>
{% endif %} {% endif %}
<hr>
<form method="post" enctype="multipart/form-data"> <form method="post" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
@ -72,6 +74,12 @@
<button type="submit" class="btn btn-outline-info">Update</button> <button type="submit" class="btn btn-outline-info">Update</button>
</div> </div>
</form> </form>
</div> <hr>
<form method="post">
{% csrf_token %}
<legend class="border-bottom mb-4"> Update your password </legend>
{{ passwordForm|crispy }}
<button type="submit" class="btn btn-outline-info">Save changes</button>
</form>
</div> </div>
{% endblock content %} {% endblock content %}

View File

@ -9,8 +9,9 @@ from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
from social_django.models import UserSocialAuth from social_django.models import UserSocialAuth
from .models import Profile from .models import Profile
def register(request): def register(request):
createProfileIfNotExist(request)
if request.method == 'POST': if request.method == 'POST':
form = UserRegisterForm(request.POST) form = UserRegisterForm(request.POST)
if form.is_valid(): if form.is_valid():
@ -25,6 +26,7 @@ def register(request):
@login_required @login_required
def profile(request): def profile(request):
createProfileIfNotExist(request)
user = request.user user = request.user
@ -51,24 +53,42 @@ def profile(request):
can_disconnect = (user.social_auth.count() > 1 or user.has_usable_password()) can_disconnect = (user.social_auth.count() > 1 or user.has_usable_password())
if request.user.has_usable_password():
PasswordForm = PasswordChangeForm
else:
PasswordForm = AdminPasswordChangeForm
if request.method == "POST": if request.method == "POST":
userForm = UserUpdateForm(request.POST, instance=request.user) userForm = UserUpdateForm(request.POST, instance=request.user)
profileForm = ProfileUpdateForm(request.POST, profileForm = ProfileUpdateForm(request.POST,
request.FILES, request.FILES,
instance=request.user.profile) instance=request.user.profile)
passwordForm = PasswordForm(request.user, request.POST)
if userForm.is_valid() and profileForm.is_valid(): if userForm.is_valid() and profileForm.is_valid():
userForm.save() userForm.save()
profileForm.save() profileForm.save()
messages.success(request, "Your account has been updated!") messages.success(request, "Your account has been updated!")
return redirect('profile') return redirect('profile')
elif passwordForm.is_valid():
passwordForm.save()
update_session_auth_hash(request, passwordForm.user)
messages.success(request, 'Your password was successfully updated!')
return redirect('profile')
else:
messages.error(request, 'Please correct the errors below.')
else: else:
userForm = UserUpdateForm(instance=request.user) userForm = UserUpdateForm(instance=request.user)
profileForm = ProfileUpdateForm(instance=request.user.profile) profileForm = ProfileUpdateForm(instance=request.user.profile)
passwordForm = PasswordForm(request.user)
context = { context = {
'userForm': userForm, 'userForm': userForm,
'profileForm': profileForm, 'profileForm': profileForm,
'passwordForm': passwordForm,
'github_login': github_login, 'github_login': github_login,
'google_login': google_login, 'google_login': google_login,
'facebook_login': facebook_login, 'facebook_login': facebook_login,
@ -79,6 +99,8 @@ def profile(request):
@login_required @login_required
def password(request): def password(request):
createProfileIfNotExist(request)
if request.user.has_usable_password(): if request.user.has_usable_password():
PasswordForm = PasswordChangeForm PasswordForm = PasswordChangeForm
else: else:
@ -96,3 +118,8 @@ def password(request):
else: else:
form = PasswordForm(request.user) form = PasswordForm(request.user)
return render(request, 'users/password.html', {'form': form}) return render(request, 'users/password.html', {'form': form})
def createProfileIfNotExist (request):
if request.user.is_authenticated and Profile.objects.filter(user=request.user).count() < 1:
Profile.objects.create(user=request.user).save()