diff --git a/media/default-header.jpg b/media/default-header.jpg new file mode 100644 index 0000000..42f9128 Binary files /dev/null and b/media/default-header.jpg differ diff --git a/media/default.jpg b/media/default-pfp.jpg similarity index 100% rename from media/default.jpg rename to media/default-pfp.jpg diff --git a/media/profile_pics/uhuh.jpg b/media/profile_pics/uhuh.jpg new file mode 100644 index 0000000..8b3fde7 Binary files /dev/null and b/media/profile_pics/uhuh.jpg differ diff --git a/news/migrations/0002_article_header.py b/news/migrations/0002_article_header.py new file mode 100644 index 0000000..5f21651 --- /dev/null +++ b/news/migrations/0002_article_header.py @@ -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'), + ), + ] diff --git a/news/migrations/0003_auto_20200815_1130.py b/news/migrations/0003_auto_20200815_1130.py new file mode 100644 index 0000000..607f7f1 --- /dev/null +++ b/news/migrations/0003_auto_20200815_1130.py @@ -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'), + ), + ] diff --git a/news/migrations/0004_article_headline.py b/news/migrations/0004_article_headline.py new file mode 100644 index 0000000..aaaf849 --- /dev/null +++ b/news/migrations/0004_article_headline.py @@ -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, + ), + ] diff --git a/news/models.py b/news/models.py index c3da620..70b14e1 100644 --- a/news/models.py +++ b/news/models.py @@ -4,16 +4,31 @@ from django.utils import timezone from django.contrib.auth.models import User from django.urls import reverse +from PIL import Image + # Create your models here. class Article(models.Model): + headline = models.TextField() content = models.TextField() date_published = models.DateTimeField(auto_now_add=True) author = models.ForeignKey(User, on_delete=models.CASCADE) likes = models.IntegerField(default=0) + header = models.ImageField(default='default-header.jpg', upload_to='article-headers') + header_caption = models.TextField(default="") def __str__(self): return f"{self.author}'s article on {self.date_published}" def get_absolute_url(self): 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) diff --git a/news/templates/news/about.html b/news/templates/news/about.html index 8dabb47..3f0ef82 100644 --- a/news/templates/news/about.html +++ b/news/templates/news/about.html @@ -1,4 +1,4 @@ {% extends 'news/base.html' %} {% block content %} -

home

+

This is the NVN about page.

{% endblock content %} diff --git a/news/templates/news/article_detail.html b/news/templates/news/article_detail.html index 0ee9e1b..bc9d291 100644 --- a/news/templates/news/article_detail.html +++ b/news/templates/news/article_detail.html @@ -6,6 +6,7 @@
{{ object.author.get_full_name }} @{{ object.author }} · {{ object.date_published }} + {% if object.author == user %}
Edit article @@ -13,6 +14,8 @@
{% endif %}
+ +

{{ article.content }}

diff --git a/news/templates/news/base.html b/news/templates/news/base.html index fc2c289..a9add2d 100644 --- a/news/templates/news/base.html +++ b/news/templates/news/base.html @@ -40,6 +40,7 @@ Logout {% else %} Login + Register {% endif %} diff --git a/news/templates/news/home.html b/news/templates/news/home.html index 9459fa0..21da872 100644 --- a/news/templates/news/home.html +++ b/news/templates/news/home.html @@ -6,9 +6,9 @@
{{ article.author.get_full_name }} - @{{ article.author }} · {{ article.date_published }} + @{{ article.author }} · {{ article.date_published }}
-

{{ article.content }}

+

{{ article.headline }}

{% endfor %} diff --git a/news/views.py b/news/views.py index 79eebc1..ba3de8e 100644 --- a/news/views.py +++ b/news/views.py @@ -16,11 +16,12 @@ from users.models import Profile # Create your views here. def about (request): + createProfileIfNotExist(request) + return render (request, 'news/about.html') def home (request): - if request.user.is_authenticated and Profile.objects.filter(user=request.user).count() < 1: - Profile.objects.create(user=request.user).save() + createProfileIfNotExist(request) context = { 'articles': Article.objects.all() @@ -29,6 +30,7 @@ def home (request): return render (request, 'news/home.html', context) class ArticleListView(ListView): + model = Article template_name = "news/home.html" context_object_name='articles' @@ -50,7 +52,7 @@ class ArticleDetailView(DetailView): class ArticleCreateView(LoginRequiredMixin, CreateView): model = Article - fields=['content'] + fields=['headline','header','header_caption','content'] def form_valid(self, form): form.instance.author = self.request.user @@ -58,7 +60,7 @@ class ArticleCreateView(LoginRequiredMixin, CreateView): class ArticleUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView): model = Article - fields=['content'] + fields=['headline','header','header_caption','content'] def form_valid(self, form): form.instance.author = self.request.user @@ -75,3 +77,7 @@ class ArticleDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView): def test_func(self): article = self.get_object() 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() diff --git a/users/forms.py b/users/forms.py index b3f1a74..82b0c8d 100644 --- a/users/forms.py +++ b/users/forms.py @@ -17,7 +17,7 @@ class UserUpdateForm(forms.ModelForm): class Meta: model = User - fields = ['username', 'email'] + fields = ['username', 'email', 'first_name', 'last_name'] class ProfileUpdateForm(forms.ModelForm): diff --git a/users/migrations/0004_auto_20200815_1130.py b/users/migrations/0004_auto_20200815_1130.py new file mode 100644 index 0000000..0e71955 --- /dev/null +++ b/users/migrations/0004_auto_20200815_1130.py @@ -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'), + ), + ] diff --git a/users/models.py b/users/models.py index c677c3e..2dc1954 100644 --- a/users/models.py +++ b/users/models.py @@ -1,5 +1,3 @@ -from django.db import models - # Create your models here. from django.db import models @@ -9,7 +7,7 @@ from PIL import Image class Profile(models.Model): 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): return f'{self.user.username} Profile' diff --git a/users/templates/users/profile.html b/users/templates/users/profile.html index 503ee53..32c2096 100644 --- a/users/templates/users/profile.html +++ b/users/templates/users/profile.html @@ -6,11 +6,12 @@

{{ user.username }}

+

{{ user.first_name }} {{ user.last_name }}

{{ user.email }}

- -

Settings

+
+

Social Settings

GitHub

{% if github_login %} @@ -18,7 +19,7 @@ {% if can_disconnect %}
{% csrf_token %} - +
{% else %} @@ -34,7 +35,7 @@ {% if can_disconnect %}
{% csrf_token %} - +
{% else %} @@ -50,7 +51,7 @@ {% if can_disconnect %}
{% csrf_token %} - +
{% else %} @@ -60,6 +61,7 @@ Connect to Facebook {% endif %} +
{% csrf_token %} @@ -72,6 +74,12 @@
- +
+
+ {% csrf_token %} + Update your password + {{ passwordForm|crispy }} + +
{% endblock content %} diff --git a/users/views.py b/users/views.py index 4be60fd..9562ffe 100644 --- a/users/views.py +++ b/users/views.py @@ -9,8 +9,9 @@ from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm from social_django.models import UserSocialAuth from .models import Profile - def register(request): + createProfileIfNotExist(request) + if request.method == 'POST': form = UserRegisterForm(request.POST) if form.is_valid(): @@ -25,12 +26,13 @@ def register(request): @login_required def profile(request): + createProfileIfNotExist(request) user = request.user if Profile.objects.filter(user=user).count() < 1: Profile.objects.create(user=user).save() - + if user.has_usable_password() is False: return redirect ('password') @@ -51,24 +53,42 @@ def profile(request): 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": userForm = UserUpdateForm(request.POST, instance=request.user) profileForm = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile) + passwordForm = PasswordForm(request.user, request.POST) + if userForm.is_valid() and profileForm.is_valid(): userForm.save() profileForm.save() messages.success(request, "Your account has been updated!") 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: userForm = UserUpdateForm(instance=request.user) profileForm = ProfileUpdateForm(instance=request.user.profile) + passwordForm = PasswordForm(request.user) context = { 'userForm': userForm, 'profileForm': profileForm, + 'passwordForm': passwordForm, 'github_login': github_login, 'google_login': google_login, 'facebook_login': facebook_login, @@ -79,6 +99,8 @@ def profile(request): @login_required def password(request): + createProfileIfNotExist(request) + if request.user.has_usable_password(): PasswordForm = PasswordChangeForm else: @@ -96,3 +118,8 @@ def password(request): else: form = PasswordForm(request.user) 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()