Spaces:
Runtime error
Runtime error
An Hang
commited on
revert-social (#50)
Browse files- src/social/admin.py +2 -2
- src/social/forms.py +9 -8
- src/social/migrations/0001_initial.py +11 -1
- src/social/migrations/0002_comment.py +0 -27
- src/social/migrations/0003_userprofile.py +0 -26
- src/social/migrations/0004_userprofile_followers.py +0 -20
- src/social/migrations/0005_auto_20210131_1615.py +0 -25
- src/social/migrations/0006_alter_comment_id_alter_post_id.py +0 -23
- src/social/models.py +5 -26
- src/social/templates/social/comment_delete.html +14 -14
- src/social/templates/social/post_delete.html +14 -14
- src/social/templates/social/post_detail.html +17 -43
- src/social/templates/social/post_edit.html +7 -9
- src/social/templates/social/post_list.html +22 -50
- src/social/templates/social/profile.html +0 -101
- src/social/templates/social/profile_edit.html +0 -30
- src/social/templates/social/search.html +0 -31
- src/social/urls.py +1 -8
- src/social/views.py +11 -151
src/social/admin.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
from django.contrib import admin
|
| 2 |
-
from .models import Post
|
| 3 |
|
| 4 |
admin.site.register(Post)
|
| 5 |
-
admin.site.register(
|
|
|
|
| 1 |
from django.contrib import admin
|
| 2 |
+
from .models import Post #, Comment
|
| 3 |
|
| 4 |
admin.site.register(Post)
|
| 5 |
+
# admin.site.register(Comment)
|
src/social/forms.py
CHANGED
|
@@ -1,13 +1,14 @@
|
|
| 1 |
from django import forms
|
| 2 |
from .models import Post, Comment
|
| 3 |
|
|
|
|
| 4 |
class PostForm(forms.ModelForm):
|
| 5 |
body = forms.CharField(
|
| 6 |
label='',
|
| 7 |
-
widget=forms.Textarea(
|
| 8 |
-
'rows': '3',
|
| 9 |
-
|
| 10 |
-
|
| 11 |
|
| 12 |
class Meta:
|
| 13 |
model = Post
|
|
@@ -16,10 +17,10 @@ class PostForm(forms.ModelForm):
|
|
| 16 |
class CommentForm(forms.ModelForm):
|
| 17 |
comment = forms.CharField(
|
| 18 |
label='',
|
| 19 |
-
widget=forms.Textarea(
|
| 20 |
-
'rows': '3',
|
| 21 |
-
|
| 22 |
-
|
| 23 |
|
| 24 |
class Meta:
|
| 25 |
model = Comment
|
|
|
|
| 1 |
from django import forms
|
| 2 |
from .models import Post, Comment
|
| 3 |
|
| 4 |
+
|
| 5 |
class PostForm(forms.ModelForm):
|
| 6 |
body = forms.CharField(
|
| 7 |
label='',
|
| 8 |
+
widget=forms.Textarea(
|
| 9 |
+
attrs={'rows': '3',
|
| 10 |
+
'placeholder': 'Say Something...'}
|
| 11 |
+
))
|
| 12 |
|
| 13 |
class Meta:
|
| 14 |
model = Post
|
|
|
|
| 17 |
class CommentForm(forms.ModelForm):
|
| 18 |
comment = forms.CharField(
|
| 19 |
label='',
|
| 20 |
+
widget=forms.Textarea(
|
| 21 |
+
attrs={'rows': '3',
|
| 22 |
+
'placeholder': 'Say Something...'}
|
| 23 |
+
))
|
| 24 |
|
| 25 |
class Meta:
|
| 26 |
model = Comment
|
src/social/migrations/0001_initial.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
# Generated by Django
|
| 2 |
|
| 3 |
from django.conf import settings
|
| 4 |
from django.db import migrations, models
|
|
@@ -24,4 +24,14 @@ class Migration(migrations.Migration):
|
|
| 24 |
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
| 25 |
],
|
| 26 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
]
|
|
|
|
| 1 |
+
# Generated by Django 3.1.4 on 2020-12-20 00:03
|
| 2 |
|
| 3 |
from django.conf import settings
|
| 4 |
from django.db import migrations, models
|
|
|
|
| 24 |
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
| 25 |
],
|
| 26 |
),
|
| 27 |
+
migrations.CreateModel(
|
| 28 |
+
name='Comment',
|
| 29 |
+
fields=[
|
| 30 |
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
| 31 |
+
('comment', models.TextField()),
|
| 32 |
+
('created_on', models.DateTimeField(default=django.utils.timezone.now)),
|
| 33 |
+
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
| 34 |
+
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='social.post')),
|
| 35 |
+
],
|
| 36 |
+
),
|
| 37 |
]
|
src/social/migrations/0002_comment.py
DELETED
|
@@ -1,27 +0,0 @@
|
|
| 1 |
-
# Generated by Django 3.1.4 on 2021-01-01 18:58
|
| 2 |
-
|
| 3 |
-
from django.conf import settings
|
| 4 |
-
from django.db import migrations, models
|
| 5 |
-
import django.db.models.deletion
|
| 6 |
-
import django.utils.timezone
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
class Migration(migrations.Migration):
|
| 10 |
-
|
| 11 |
-
dependencies = [
|
| 12 |
-
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
| 13 |
-
('social', '0001_initial'),
|
| 14 |
-
]
|
| 15 |
-
|
| 16 |
-
operations = [
|
| 17 |
-
migrations.CreateModel(
|
| 18 |
-
name='Comment',
|
| 19 |
-
fields=[
|
| 20 |
-
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
| 21 |
-
('comment', models.TextField()),
|
| 22 |
-
('created_on', models.DateTimeField(default=django.utils.timezone.now)),
|
| 23 |
-
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
| 24 |
-
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='social.post')),
|
| 25 |
-
],
|
| 26 |
-
),
|
| 27 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/social/migrations/0003_userprofile.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
| 1 |
-
# Generated by Django 3.1.4 on 2021-01-17 18:24
|
| 2 |
-
|
| 3 |
-
from django.db import migrations, models
|
| 4 |
-
import django.db.models.deletion
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
class Migration(migrations.Migration):
|
| 8 |
-
|
| 9 |
-
dependencies = [
|
| 10 |
-
('auth', '0012_alter_user_first_name_max_length'),
|
| 11 |
-
('social', '0002_comment'),
|
| 12 |
-
]
|
| 13 |
-
|
| 14 |
-
operations = [
|
| 15 |
-
migrations.CreateModel(
|
| 16 |
-
name='UserProfile',
|
| 17 |
-
fields=[
|
| 18 |
-
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='profile', serialize=False, to='auth.user', verbose_name='user')),
|
| 19 |
-
('name', models.CharField(blank=True, max_length=30, null=True)),
|
| 20 |
-
('bio', models.TextField(blank=True, max_length=500, null=True)),
|
| 21 |
-
('birth_date', models.DateField(blank=True, null=True)),
|
| 22 |
-
('location', models.CharField(blank=True, max_length=100, null=True)),
|
| 23 |
-
('picture', models.ImageField(blank=True, default='uploads/profile_pictures/default.png', upload_to='uploads/profile_pictures')),
|
| 24 |
-
],
|
| 25 |
-
),
|
| 26 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/social/migrations/0004_userprofile_followers.py
DELETED
|
@@ -1,20 +0,0 @@
|
|
| 1 |
-
# Generated by Django 3.1.4 on 2021-01-26 00:21
|
| 2 |
-
|
| 3 |
-
from django.conf import settings
|
| 4 |
-
from django.db import migrations, models
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
class Migration(migrations.Migration):
|
| 8 |
-
|
| 9 |
-
dependencies = [
|
| 10 |
-
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
| 11 |
-
('social', '0003_userprofile'),
|
| 12 |
-
]
|
| 13 |
-
|
| 14 |
-
operations = [
|
| 15 |
-
migrations.AddField(
|
| 16 |
-
model_name='userprofile',
|
| 17 |
-
name='followers',
|
| 18 |
-
field=models.ManyToManyField(blank=True, related_name='followers', to=settings.AUTH_USER_MODEL),
|
| 19 |
-
),
|
| 20 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/social/migrations/0005_auto_20210131_1615.py
DELETED
|
@@ -1,25 +0,0 @@
|
|
| 1 |
-
# Generated by Django 3.1.4 on 2021-01-31 16:15
|
| 2 |
-
|
| 3 |
-
from django.conf import settings
|
| 4 |
-
from django.db import migrations, models
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
class Migration(migrations.Migration):
|
| 8 |
-
|
| 9 |
-
dependencies = [
|
| 10 |
-
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
| 11 |
-
('social', '0004_userprofile_followers'),
|
| 12 |
-
]
|
| 13 |
-
|
| 14 |
-
operations = [
|
| 15 |
-
migrations.AddField(
|
| 16 |
-
model_name='post',
|
| 17 |
-
name='dislikes',
|
| 18 |
-
field=models.ManyToManyField(blank=True, related_name='dislikes', to=settings.AUTH_USER_MODEL),
|
| 19 |
-
),
|
| 20 |
-
migrations.AddField(
|
| 21 |
-
model_name='post',
|
| 22 |
-
name='likes',
|
| 23 |
-
field=models.ManyToManyField(blank=True, related_name='likes', to=settings.AUTH_USER_MODEL),
|
| 24 |
-
),
|
| 25 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/social/migrations/0006_alter_comment_id_alter_post_id.py
DELETED
|
@@ -1,23 +0,0 @@
|
|
| 1 |
-
# Generated by Django 5.0.3 on 2024-04-01 10:12
|
| 2 |
-
|
| 3 |
-
from django.db import migrations, models
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
class Migration(migrations.Migration):
|
| 7 |
-
|
| 8 |
-
dependencies = [
|
| 9 |
-
('social', '0005_auto_20210131_1615'),
|
| 10 |
-
]
|
| 11 |
-
|
| 12 |
-
operations = [
|
| 13 |
-
migrations.AlterField(
|
| 14 |
-
model_name='comment',
|
| 15 |
-
name='id',
|
| 16 |
-
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
| 17 |
-
),
|
| 18 |
-
migrations.AlterField(
|
| 19 |
-
model_name='post',
|
| 20 |
-
name='id',
|
| 21 |
-
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
| 22 |
-
),
|
| 23 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/social/models.py
CHANGED
|
@@ -1,37 +1,16 @@
|
|
| 1 |
from django.db import models
|
| 2 |
from django.utils import timezone
|
| 3 |
from django.contrib.auth.models import User
|
| 4 |
-
from django.db.models.signals import post_save
|
| 5 |
-
from django.dispatch import receiver
|
| 6 |
|
| 7 |
|
| 8 |
class Post(models.Model):
|
| 9 |
body = models.TextField()
|
| 10 |
created_on = models.DateTimeField(default=timezone.now)
|
| 11 |
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
| 12 |
-
likes = models.ManyToManyField(User, blank=True, related_name='likes')
|
| 13 |
-
dislikes = models.ManyToManyField(User, blank=True, related_name='dislikes')
|
| 14 |
|
| 15 |
-
class Comment(models.Model):
|
| 16 |
-
comment = models.TextField()
|
| 17 |
-
created_on = models.DateTimeField(default=timezone.now)
|
| 18 |
-
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
| 19 |
-
post = models.ForeignKey('Post', on_delete=models.CASCADE)
|
| 20 |
-
|
| 21 |
-
class UserProfile(models.Model):
|
| 22 |
-
user = models.OneToOneField(User, primary_key=True, verbose_name='user', related_name='profile', on_delete=models.CASCADE)
|
| 23 |
-
name = models.CharField(max_length=30, blank=True, null=True)
|
| 24 |
-
bio = models.TextField(max_length=500, blank=True, null=True)
|
| 25 |
-
birth_date=models.DateField(null=True, blank=True)
|
| 26 |
-
location = models.CharField(max_length=100, blank=True, null=True)
|
| 27 |
-
picture = models.ImageField(upload_to='uploads/profile_pictures', default='uploads/profile_pictures/default.png', blank=True)
|
| 28 |
-
followers = models.ManyToManyField(User, blank=True, related_name='followers')
|
| 29 |
-
|
| 30 |
-
@receiver(post_save, sender=User)
|
| 31 |
-
def create_user_profile(sender, instance, created, **kwargs):
|
| 32 |
-
if created:
|
| 33 |
-
UserProfile.objects.create(user=instance)
|
| 34 |
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
|
|
|
|
|
|
|
|
| 1 |
from django.db import models
|
| 2 |
from django.utils import timezone
|
| 3 |
from django.contrib.auth.models import User
|
|
|
|
|
|
|
| 4 |
|
| 5 |
|
| 6 |
class Post(models.Model):
|
| 7 |
body = models.TextField()
|
| 8 |
created_on = models.DateTimeField(default=timezone.now)
|
| 9 |
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
|
|
|
|
|
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
+
class Comment(models.Model):
|
| 13 |
+
comment = models.TextField()
|
| 14 |
+
created_on = models.DateTimeField(default=timezone.now)
|
| 15 |
+
post = models.ForeignKey('Post', on_delete=models.CASCADE)
|
| 16 |
+
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
src/social/templates/social/comment_delete.html
CHANGED
|
@@ -1,24 +1,24 @@
|
|
| 1 |
{% extends 'landing/base.html' %}
|
|
|
|
| 2 |
|
| 3 |
{% block content %}
|
| 4 |
<div class="container">
|
| 5 |
<div class="row mt-5">
|
| 6 |
-
<div class="col-md-
|
| 7 |
-
<a href="{% url 'post-detail' object.post.pk %}" class="btn btn-light">Back
|
| 8 |
</div>
|
| 9 |
</div>
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
<
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
<
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
</div>
|
| 22 |
</div>
|
| 23 |
</div>
|
| 24 |
{% endblock content %}
|
|
|
|
| 1 |
{% extends 'landing/base.html' %}
|
| 2 |
+
{% load crispy_forms_tags %}
|
| 3 |
|
| 4 |
{% block content %}
|
| 5 |
<div class="container">
|
| 6 |
<div class="row mt-5">
|
| 7 |
+
<div class="col-md-3 col-sm-6">
|
| 8 |
+
<a href="{% url 'post-detail' object.post.pk %}" class="btn btn-light">Back to Feed</a>
|
| 9 |
</div>
|
| 10 |
</div>
|
| 11 |
+
<div class="row justify-content-center mt-5">
|
| 12 |
+
<div class="col-md-5 col-sm-12">
|
| 13 |
+
<h5>Are You Sure?</h5>
|
| 14 |
+
<p>You are about to delete this comment, this cannot be undone.</p>
|
| 15 |
+
<form method="POST">
|
| 16 |
+
{% csrf_token %}
|
| 17 |
+
<div class="d-grid gap-2">
|
| 18 |
+
<button type="submit" class="btn btn-danger">Delete</button>
|
| 19 |
+
</div>
|
| 20 |
+
</form>
|
| 21 |
+
</div>
|
|
|
|
| 22 |
</div>
|
| 23 |
</div>
|
| 24 |
{% endblock content %}
|
src/social/templates/social/post_delete.html
CHANGED
|
@@ -1,24 +1,24 @@
|
|
| 1 |
{% extends 'landing/base.html' %}
|
|
|
|
| 2 |
|
| 3 |
{% block content %}
|
| 4 |
<div class="container">
|
| 5 |
<div class="row mt-5">
|
| 6 |
-
<div class="col-md-
|
| 7 |
-
<a href="{% url 'post-detail' object.pk %}" class="btn btn-light">Back
|
| 8 |
</div>
|
| 9 |
</div>
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
<
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
<
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
</div>
|
| 22 |
</div>
|
| 23 |
</div>
|
| 24 |
{% endblock content %}
|
|
|
|
| 1 |
{% extends 'landing/base.html' %}
|
| 2 |
+
{% load crispy_forms_tags %}
|
| 3 |
|
| 4 |
{% block content %}
|
| 5 |
<div class="container">
|
| 6 |
<div class="row mt-5">
|
| 7 |
+
<div class="col-md-3 col-sm-6">
|
| 8 |
+
<a href="{% url 'post-detail' object.pk %}" class="btn btn-light">Back to Feed</a>
|
| 9 |
</div>
|
| 10 |
</div>
|
| 11 |
+
<div class="row justify-content-center mt-5">
|
| 12 |
+
<div class="col-md-5 col-sm-12">
|
| 13 |
+
<h5>Are You Sure?</h5>
|
| 14 |
+
<p>You are about to delete this post, this cannot be undone.</p>
|
| 15 |
+
<form method="POST">
|
| 16 |
+
{% csrf_token %}
|
| 17 |
+
<div class="d-grid gap-2">
|
| 18 |
+
<button type="submit" class="btn btn-danger">Delete</button>
|
| 19 |
+
</div>
|
| 20 |
+
</form>
|
| 21 |
+
</div>
|
|
|
|
| 22 |
</div>
|
| 23 |
</div>
|
| 24 |
{% endblock content %}
|
src/social/templates/social/post_detail.html
CHANGED
|
@@ -4,47 +4,28 @@
|
|
| 4 |
{% block content %}
|
| 5 |
<div class="container">
|
| 6 |
<div class="row mt-5">
|
| 7 |
-
<div class="col-md-
|
| 8 |
-
<a href="{% url 'post-list' %}" class="btn btn-light">Back
|
| 9 |
</div>
|
| 10 |
</div>
|
| 11 |
-
|
| 12 |
<div class="row justify-content-center mt-3">
|
| 13 |
<div class="col-md-5 col-sm-12 border-bottom">
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
<img class="round-circle post-img" height="30" width="30" src="{{ post.author.profile.picture.url }}" />
|
| 17 |
-
</a>
|
| 18 |
-
<p class="post-text">
|
| 19 |
-
<a class="text-primary post-link" href="{% url 'profile' post.author.profile.pk %}">@{{ post.author }}</a> {{ post.created_on }}
|
| 20 |
-
</p>
|
| 21 |
-
</div>
|
| 22 |
{% if request.user == post.author %}
|
| 23 |
-
|
| 24 |
-
|
| 25 |
{% endif %}
|
|
|
|
| 26 |
<p>{{ post.body }}</p>
|
| 27 |
-
|
| 28 |
-
<div class="d-flex flex-row">
|
| 29 |
-
<form method="POST" action="{% url 'like' post.pk %}">
|
| 30 |
-
{% csrf_token %}
|
| 31 |
-
<input type="hidden" name="next" value="{{ request.path }}">
|
| 32 |
-
<button class="remove-default-btn" type="submit">
|
| 33 |
-
<i class="far fa-thumbs-up"> <span>{{ post.likes.all.count }}</span></i>
|
| 34 |
-
</button>
|
| 35 |
-
</form>
|
| 36 |
-
|
| 37 |
-
<form method="POST" action="{% url 'dislike' post.pk %}">
|
| 38 |
-
{% csrf_token %}
|
| 39 |
-
<input type="hidden" name="next" value="{{ request.path }}">
|
| 40 |
-
<button class="remove-default-btn" type="submit">
|
| 41 |
-
<i class="far fa-thumbs-down"> <span>{{ post.dislikes.all.count }}</span></i>
|
| 42 |
-
</button>
|
| 43 |
-
</form>
|
| 44 |
-
</div>
|
| 45 |
</div>
|
| 46 |
</div>
|
| 47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
<div class="row justify-content-center mt-3 mb-5">
|
| 49 |
<div class="col-md-5 col-sm-12">
|
| 50 |
<form method="POST">
|
|
@@ -57,19 +38,12 @@
|
|
| 57 |
</div>
|
| 58 |
</div>
|
| 59 |
{% for comment in comments %}
|
| 60 |
-
<div class="row justify-content-center mt-3 mb-5">
|
| 61 |
-
<div class="col-md-5 col-sm-12
|
| 62 |
<p>
|
| 63 |
-
<
|
| 64 |
-
<a href="{% url 'profile' comment.author.profile.pk %}">
|
| 65 |
-
<img class="round-circle post-img" height="30" width="30" src="{{ comment.author.profile.picture.url }}" />
|
| 66 |
-
</a>
|
| 67 |
-
<p class="post-text">
|
| 68 |
-
<a class="text-primary post-link" href="{% url 'profile' comment.author.profile.pk %}">@{{ comment.author }}</a> {{ comment.created_on }}
|
| 69 |
-
</p>
|
| 70 |
-
</div>
|
| 71 |
{% if request.user == comment.author %}
|
| 72 |
-
|
| 73 |
{% endif %}
|
| 74 |
</p>
|
| 75 |
<p>{{ comment.comment }}</p>
|
|
@@ -77,4 +51,4 @@
|
|
| 77 |
</div>
|
| 78 |
{% endfor %}
|
| 79 |
</div>
|
| 80 |
-
{% endblock content %}
|
|
|
|
| 4 |
{% block content %}
|
| 5 |
<div class="container">
|
| 6 |
<div class="row mt-5">
|
| 7 |
+
<div class="col-md-3 col-sm-6">
|
| 8 |
+
<a href="{% url 'post-list' %}" class="btn btn-light">Back to Feed</a>
|
| 9 |
</div>
|
| 10 |
</div>
|
|
|
|
| 11 |
<div class="row justify-content-center mt-3">
|
| 12 |
<div class="col-md-5 col-sm-12 border-bottom">
|
| 13 |
+
<p>
|
| 14 |
+
<strong>{{ post.author }}</strong> {{ post.created_on }}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
{% if request.user == post.author %}
|
| 16 |
+
<a href="{% url 'post-edit' post.pk %}" style="color: #333;"><i class="far fa-edit"></i></a>
|
| 17 |
+
<a href="{% url 'post-delete' post.pk %}" style="color: #333;"><i class="fas fa-trash"></i></a>
|
| 18 |
{% endif %}
|
| 19 |
+
</p>
|
| 20 |
<p>{{ post.body }}</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
</div>
|
| 22 |
</div>
|
| 23 |
|
| 24 |
+
<div class="row justify-content-center mt-3">
|
| 25 |
+
<div class="col-md-5 col-sm-12">
|
| 26 |
+
<h5>Add a Comment!</h5>
|
| 27 |
+
</div>
|
| 28 |
+
</div>
|
| 29 |
<div class="row justify-content-center mt-3 mb-5">
|
| 30 |
<div class="col-md-5 col-sm-12">
|
| 31 |
<form method="POST">
|
|
|
|
| 38 |
</div>
|
| 39 |
</div>
|
| 40 |
{% for comment in comments %}
|
| 41 |
+
<div class="row justify-content-center mt-3 mb-5 border-bottom">
|
| 42 |
+
<div class="col-md-5 col-sm-12">
|
| 43 |
<p>
|
| 44 |
+
<strong>{{ comment.author }}</strong> {{ comment.created_on }}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
{% if request.user == comment.author %}
|
| 46 |
+
<a href="{% url 'comment-delete' post.pk comment.pk %}" style="color: #333;"><i class="fas fa-trash"></i></a>
|
| 47 |
{% endif %}
|
| 48 |
</p>
|
| 49 |
<p>{{ comment.comment }}</p>
|
|
|
|
| 51 |
</div>
|
| 52 |
{% endfor %}
|
| 53 |
</div>
|
| 54 |
+
{% endblock content %}
|
src/social/templates/social/post_edit.html
CHANGED
|
@@ -4,19 +4,17 @@
|
|
| 4 |
{% block content %}
|
| 5 |
<div class="container">
|
| 6 |
<div class="row mt-5">
|
| 7 |
-
<div class="col-md-
|
| 8 |
-
<a href="{% url 'post-detail' object.pk %}" class="btn btn-light">Back
|
| 9 |
</div>
|
| 10 |
</div>
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
<h5>Update Your Post!</h5>
|
| 15 |
</div>
|
| 16 |
</div>
|
| 17 |
-
|
| 18 |
<div class="row justify-content-center mt-3 mb-5">
|
| 19 |
-
<div class="col-md-5 col-sm-12
|
| 20 |
<form method="POST">
|
| 21 |
{% csrf_token %}
|
| 22 |
{{ form | crispy }}
|
|
@@ -27,4 +25,4 @@
|
|
| 27 |
</div>
|
| 28 |
</div>
|
| 29 |
</div>
|
| 30 |
-
{% endblock content %}
|
|
|
|
| 4 |
{% block content %}
|
| 5 |
<div class="container">
|
| 6 |
<div class="row mt-5">
|
| 7 |
+
<div class="col-md-3 col-sm-6">
|
| 8 |
+
<a href="{% url 'post-detail' object.pk %}" class="btn btn-light">Back to Feed</a>
|
| 9 |
</div>
|
| 10 |
</div>
|
| 11 |
+
<div class="row justify-content-center mt-5">
|
| 12 |
+
<div class="col-md-5 col-sm-12">
|
| 13 |
+
<h5>Update Your Post</h5>
|
|
|
|
| 14 |
</div>
|
| 15 |
</div>
|
|
|
|
| 16 |
<div class="row justify-content-center mt-3 mb-5">
|
| 17 |
+
<div class="col-md-5 col-sm-12">
|
| 18 |
<form method="POST">
|
| 19 |
{% csrf_token %}
|
| 20 |
{{ form | crispy }}
|
|
|
|
| 25 |
</div>
|
| 26 |
</div>
|
| 27 |
</div>
|
| 28 |
+
{% endblock content %}
|
src/social/templates/social/post_list.html
CHANGED
|
@@ -2,59 +2,31 @@
|
|
| 2 |
{% load crispy_forms_tags %}
|
| 3 |
|
| 4 |
{% block content %}
|
| 5 |
-
<div class="container">
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
</div>
|
| 11 |
-
|
| 12 |
-
<div class="row justify-content-center mt-3 mb-5">
|
| 13 |
-
<div class="col-md-5 col-sm-12 border-bottom">
|
| 14 |
-
<form method="POST">
|
| 15 |
-
{% csrf_token %}
|
| 16 |
-
{{ form | crispy }}
|
| 17 |
-
<div class="d-grid gap-2">
|
| 18 |
-
<button class="btn btn-success mt-3">Submit!</button>
|
| 19 |
-
</div>
|
| 20 |
-
</form>
|
| 21 |
</div>
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
</
|
| 31 |
-
<p class="post-text">
|
| 32 |
-
<a class="text-primary post-link" href="{% url 'profile' post.author.profile.pk %}">@{{ post.author }}</a> {{ post.created_on }}
|
| 33 |
-
</p>
|
| 34 |
</div>
|
| 35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
<p>{{ post.body }}</p>
|
| 37 |
-
<a href="{% url 'post-detail' post.pk %}"
|
| 38 |
</div>
|
| 39 |
-
|
| 40 |
-
<div class="d-flex flex-row">
|
| 41 |
-
<form method="POST" action="{% url 'like' post.pk %}">
|
| 42 |
-
{% csrf_token %}
|
| 43 |
-
<input type="hidden" name="next" value="{{ request.path }}">
|
| 44 |
-
<button class="remove-default-btn" type="submit">
|
| 45 |
-
<i class="far fa-thumbs-up"> <span>{{ post.likes.all.count }}</span></i>
|
| 46 |
-
</button>
|
| 47 |
-
</form>
|
| 48 |
-
|
| 49 |
-
<form method="POST" action="{% url 'dislike' post.pk %}">
|
| 50 |
-
{% csrf_token %}
|
| 51 |
-
<input type="hidden" name="next" value="{{ request.path }}">
|
| 52 |
-
<button class="remove-default-btn" type="submit">
|
| 53 |
-
<i class="far fa-thumbs-down"> <span>{{ post.dislikes.all.count }}</span></i>
|
| 54 |
-
</button>
|
| 55 |
-
</form>
|
| 56 |
</div>
|
|
|
|
| 57 |
</div>
|
| 58 |
-
|
| 59 |
-
</div>
|
| 60 |
-
{% endblock content %}
|
|
|
|
| 2 |
{% load crispy_forms_tags %}
|
| 3 |
|
| 4 |
{% block content %}
|
| 5 |
+
<div class="container">
|
| 6 |
+
<div class="row justify-content-center mt-3">
|
| 7 |
+
<div class="col-md-5 col-sm-12">
|
| 8 |
+
<h5>Add a Post!</h5>
|
| 9 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
</div>
|
| 11 |
+
<div class="row justify-content-center mt-3 mb-5">
|
| 12 |
+
<div class="col-md-5 col-sm-12">
|
| 13 |
+
<form method="POST">
|
| 14 |
+
{% csrf_token %}
|
| 15 |
+
{{ form | crispy }}
|
| 16 |
+
<div class="d-grid gap-2">
|
| 17 |
+
<button class="btn btn-success mt-3">Submit!</button>
|
| 18 |
+
</div>
|
| 19 |
+
</form>
|
|
|
|
|
|
|
|
|
|
| 20 |
</div>
|
| 21 |
+
</div>
|
| 22 |
+
{% for post in post_list %}
|
| 23 |
+
<div class="row justify-content-center mt-3">
|
| 24 |
+
<div class="col-md-5 col-sm-12 border-bottom position-relative">
|
| 25 |
+
<p><strong>{{ post.author }}</strong> {{ post.created_on }}</p>
|
| 26 |
<p>{{ post.body }}</p>
|
| 27 |
+
<a class="stretched-link" href="{% url 'post-detail' post.pk %}"></a>
|
| 28 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
</div>
|
| 30 |
+
{% endfor %}
|
| 31 |
</div>
|
| 32 |
+
{% endblock content %}
|
|
|
|
|
|
src/social/templates/social/profile.html
DELETED
|
@@ -1,101 +0,0 @@
|
|
| 1 |
-
{% extends 'landing/base.html' %}
|
| 2 |
-
|
| 3 |
-
{% block content %}
|
| 4 |
-
<div class="container">
|
| 5 |
-
<div class="row mt-5">
|
| 6 |
-
<div class="col-md-3 col-sm-6">
|
| 7 |
-
<a href="{% url 'post-list' %}" class="btn btn-light">Back to Feed</a>
|
| 8 |
-
</div>
|
| 9 |
-
</div>
|
| 10 |
-
|
| 11 |
-
<div class="row justify-content-center mt-5">
|
| 12 |
-
<div class="card shadow-sm col-md-8 col-sm-12 border-bottom px-5 pt-3">
|
| 13 |
-
<img src="{{ profile.picture.url }}" class="rounded-circle" width="100" height="100" />
|
| 14 |
-
{% if profile.name %}
|
| 15 |
-
<h3 class="py-4">{{ profile.name }}
|
| 16 |
-
<span>
|
| 17 |
-
{% if request.user == user %}
|
| 18 |
-
<a href="{% url 'profile-edit' profile.pk %}" class="edit-color"><i class="far fa-edit"></i></a>
|
| 19 |
-
{% endif %}
|
| 20 |
-
</span>
|
| 21 |
-
{% else %}
|
| 22 |
-
<h3 class="py-4">{{ user.username }}
|
| 23 |
-
<span>
|
| 24 |
-
{% if request.user == user %}
|
| 25 |
-
<a href="{% url 'profile-edit' profile.pk %}" class="edit-color"><i class="far fa-edit"></i></a>
|
| 26 |
-
{% endif %}
|
| 27 |
-
</span>
|
| 28 |
-
</h3>
|
| 29 |
-
{% endif %}
|
| 30 |
-
</h3>
|
| 31 |
-
|
| 32 |
-
{% if profile.location %}
|
| 33 |
-
<p>{{ profile.location }}</p>
|
| 34 |
-
{% endif %}
|
| 35 |
-
|
| 36 |
-
{% if profile.birth_date %}
|
| 37 |
-
<p>{{ profile.birth_date }}</p>
|
| 38 |
-
{% endif %}
|
| 39 |
-
|
| 40 |
-
{% if profile.bio %}
|
| 41 |
-
<p>{{ profile.bio }}</p>
|
| 42 |
-
{% endif %}
|
| 43 |
-
|
| 44 |
-
<div class="mb-3">
|
| 45 |
-
<p>Followers: {{ number_of_followers }}</p>
|
| 46 |
-
{% if user == request.user %}
|
| 47 |
-
{% else %}
|
| 48 |
-
{% if is_following %}
|
| 49 |
-
<form method="POST" action="{% url 'remove-follower' profile.pk %}">
|
| 50 |
-
{% csrf_token %}
|
| 51 |
-
<button class="btn btn-outline-danger" type="submit">Unfollow</button>
|
| 52 |
-
</form>
|
| 53 |
-
{% else %}
|
| 54 |
-
<form method="POST" action="{% url 'add-follower' profile.pk %}">
|
| 55 |
-
{% csrf_token %}
|
| 56 |
-
<button class="btn btn-outline-success" type="submit">Follow</button>
|
| 57 |
-
</form>
|
| 58 |
-
{% endif %}
|
| 59 |
-
{% endif %}
|
| 60 |
-
</div>
|
| 61 |
-
</div>
|
| 62 |
-
</div>
|
| 63 |
-
|
| 64 |
-
{% for post in posts %}
|
| 65 |
-
<div class="row justify-content-center mt-5">
|
| 66 |
-
<div class="col-md-8 col-sm-12 border-bottom">
|
| 67 |
-
<div>
|
| 68 |
-
<a href="{% url 'profile' post.author.profile.pk %}">
|
| 69 |
-
<img class="round-circle post-img" height="30" width="30" src="{{ post.author.profile.picture.url }}" />
|
| 70 |
-
</a>
|
| 71 |
-
<p class="post-text">
|
| 72 |
-
<a class="text-primary post-link" href="{% url 'profile' post.author.profile.pk %}">@{{ post.author }}</a> {{ post.created_on }}
|
| 73 |
-
</p>
|
| 74 |
-
</div>
|
| 75 |
-
<div class="position-relative">
|
| 76 |
-
<p>{{ post.body }}</p>
|
| 77 |
-
<a href="{% url 'post-detail' post.pk %}" class="stretched-link"></a>
|
| 78 |
-
</div>
|
| 79 |
-
|
| 80 |
-
<div class="d-flex flex-row">
|
| 81 |
-
<form method="POST" action="{% url 'like' post.pk %}">
|
| 82 |
-
{% csrf_token %}
|
| 83 |
-
<input type="hidden" name="next" value="{{ request.path }}">
|
| 84 |
-
<button class="remove-default-btn" type="submit">
|
| 85 |
-
<i class="far fa-thumbs-up"> <span>{{ post.likes.all.count }}</span></i>
|
| 86 |
-
</button>
|
| 87 |
-
</form>
|
| 88 |
-
|
| 89 |
-
<form method="POST" action="{% url 'dislike' post.pk %}">
|
| 90 |
-
{% csrf_token %}
|
| 91 |
-
<input type="hidden" name="next" value="{{ request.path }}">
|
| 92 |
-
<button class="remove-default-btn" type="submit">
|
| 93 |
-
<i class="far fa-thumbs-down"> <span>{{ post.dislikes.all.count }}</span></i>
|
| 94 |
-
</button>
|
| 95 |
-
</form>
|
| 96 |
-
</div>
|
| 97 |
-
</div>
|
| 98 |
-
</div>
|
| 99 |
-
{% endfor %}
|
| 100 |
-
</div>
|
| 101 |
-
{% endblock content %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/social/templates/social/profile_edit.html
DELETED
|
@@ -1,30 +0,0 @@
|
|
| 1 |
-
{% extends 'landing/base.html' %}
|
| 2 |
-
{% load crispy_forms_tags %}
|
| 3 |
-
|
| 4 |
-
{% block content %}
|
| 5 |
-
<div class="container">
|
| 6 |
-
<div class="row mt-5">
|
| 7 |
-
<div class="col-md-5 col-sm-6">
|
| 8 |
-
<a href="{% url 'profile' object.pk %}" class="btn btn-light">Back To Profile</a>
|
| 9 |
-
</div>
|
| 10 |
-
</div>
|
| 11 |
-
|
| 12 |
-
<div class="row justify-content-center mt-3">
|
| 13 |
-
<div class="col-md-5 col-sm-12 border-bottom">
|
| 14 |
-
<h5>Update Your Profile</h5>
|
| 15 |
-
</div>
|
| 16 |
-
</div>
|
| 17 |
-
|
| 18 |
-
<div class="row justify-content-center mt-3 mb-5">
|
| 19 |
-
<div class="col-md-5 col-sm-12 border-bottom">
|
| 20 |
-
<form method="POST" enctype="multipart/form-data">
|
| 21 |
-
{% csrf_token %}
|
| 22 |
-
{{ form | crispy }}
|
| 23 |
-
<div class="d-grid gap-2">
|
| 24 |
-
<button class="btn btn-success mt-3">Submit!</button>
|
| 25 |
-
</div>
|
| 26 |
-
</form>
|
| 27 |
-
</div>
|
| 28 |
-
</div>
|
| 29 |
-
</div>
|
| 30 |
-
{% endblock content %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/social/templates/social/search.html
DELETED
|
@@ -1,31 +0,0 @@
|
|
| 1 |
-
{% extends 'landing/base.html' %}
|
| 2 |
-
|
| 3 |
-
{% block content %}
|
| 4 |
-
<div class="container">
|
| 5 |
-
<div class="row mt-5">
|
| 6 |
-
<div class="col-md-5 col-sm-6">
|
| 7 |
-
<a href="{% url 'post-list' %}" class="btn btn-light">Back To Feed</a>
|
| 8 |
-
</div>
|
| 9 |
-
</div>
|
| 10 |
-
|
| 11 |
-
{% for profile in profile_list %}
|
| 12 |
-
<div class="row justify-content-center mt-3">
|
| 13 |
-
<div class="col-md-5 col-sm-12 border-bottom position-relative">
|
| 14 |
-
<div>
|
| 15 |
-
<a href="{% url 'profile' profile.pk %}">
|
| 16 |
-
<img class="round-circle post-img" height="30" width="30" src="{{ profile.picture.url }}" />
|
| 17 |
-
</a>
|
| 18 |
-
<p class="post-text">
|
| 19 |
-
<a class="text-primary post-link" href="{% url 'profile' profile.pk %}">@{{ profile.user }}</a>
|
| 20 |
-
</p>
|
| 21 |
-
</div>
|
| 22 |
-
<p><a class="text-primary post-link" href="{% url 'profile' profile.pk %}">@{{ profile.user }}</a></p>
|
| 23 |
-
{% if profile.location %}
|
| 24 |
-
<p>{{ profile.location }}</p>
|
| 25 |
-
{% endif %}
|
| 26 |
-
<p>Followers: {{ profile.followers.all.count }}</p>
|
| 27 |
-
</div>
|
| 28 |
-
</div>
|
| 29 |
-
{% endfor %}
|
| 30 |
-
</div>
|
| 31 |
-
{% endblock content %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/social/urls.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
from django.urls import path
|
| 2 |
-
from .views import PostListView, PostDetailView, PostEditView, PostDeleteView, CommentDeleteView
|
| 3 |
|
| 4 |
urlpatterns = [
|
| 5 |
path('', PostListView.as_view(), name='post-list'),
|
|
@@ -7,11 +7,4 @@ urlpatterns = [
|
|
| 7 |
path('post/edit/<int:pk>/', PostEditView.as_view(), name='post-edit'),
|
| 8 |
path('post/delete/<int:pk>/', PostDeleteView.as_view(), name='post-delete'),
|
| 9 |
path('post/<int:post_pk>/comment/delete/<int:pk>/', CommentDeleteView.as_view(), name='comment-delete'),
|
| 10 |
-
path('post/<int:pk>/like', AddLike.as_view(), name='like'),
|
| 11 |
-
path('post/<int:pk>/dislike', AddDislike.as_view(), name='dislike'),
|
| 12 |
-
path('profile/<int:pk>/', ProfileView.as_view(), name='profile'),
|
| 13 |
-
path('profile/edit/<int:pk>/', ProfileEditView.as_view(), name='profile-edit'),
|
| 14 |
-
path('profile/<int:pk>/followers/add', AddFollower.as_view(), name='add-follower'),
|
| 15 |
-
path('profile/<int:pk>/followers/remove', RemoveFollower.as_view(), name='remove-follower'),
|
| 16 |
-
path('search/', UserSearch.as_view(), name='profile-search'),
|
| 17 |
]
|
|
|
|
| 1 |
from django.urls import path
|
| 2 |
+
from .views import PostListView, PostDetailView, PostEditView, PostDeleteView, CommentDeleteView
|
| 3 |
|
| 4 |
urlpatterns = [
|
| 5 |
path('', PostListView.as_view(), name='post-list'),
|
|
|
|
| 7 |
path('post/edit/<int:pk>/', PostEditView.as_view(), name='post-edit'),
|
| 8 |
path('post/delete/<int:pk>/', PostDeleteView.as_view(), name='post-delete'),
|
| 9 |
path('post/<int:post_pk>/comment/delete/<int:pk>/', CommentDeleteView.as_view(), name='comment-delete'),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
]
|
src/social/views.py
CHANGED
|
@@ -1,34 +1,25 @@
|
|
| 1 |
-
from django.shortcuts import render
|
| 2 |
-
from django.db.models import Q
|
| 3 |
from django.urls import reverse_lazy
|
| 4 |
-
from django.http import HttpResponseRedirect
|
| 5 |
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
|
| 6 |
from django.views import View
|
| 7 |
-
from .models import Post, Comment, UserProfile
|
| 8 |
-
from .forms import PostForm, CommentForm
|
| 9 |
from django.views.generic.edit import UpdateView, DeleteView
|
|
|
|
|
|
|
| 10 |
|
| 11 |
|
| 12 |
class PostListView(LoginRequiredMixin, View):
|
| 13 |
def get(self, request, *args, **kwargs):
|
| 14 |
-
|
| 15 |
-
posts = Post.objects.filter(
|
| 16 |
-
author__profile__followers__in=[logged_in_user.id]
|
| 17 |
-
).order_by('-created_on')
|
| 18 |
form = PostForm()
|
| 19 |
|
| 20 |
context = {
|
| 21 |
'post_list': posts,
|
| 22 |
'form': form,
|
| 23 |
}
|
| 24 |
-
|
| 25 |
return render(request, 'social/post_list.html', context)
|
| 26 |
|
| 27 |
def post(self, request, *args, **kwargs):
|
| 28 |
-
|
| 29 |
-
posts = Post.objects.filter(
|
| 30 |
-
author__profile__followers__in=[logged_in_user.id]
|
| 31 |
-
).order_by('-created_on')
|
| 32 |
form = PostForm(request.POST)
|
| 33 |
|
| 34 |
if form.is_valid():
|
|
@@ -40,14 +31,12 @@ class PostListView(LoginRequiredMixin, View):
|
|
| 40 |
'post_list': posts,
|
| 41 |
'form': form,
|
| 42 |
}
|
| 43 |
-
|
| 44 |
return render(request, 'social/post_list.html', context)
|
| 45 |
|
| 46 |
class PostDetailView(LoginRequiredMixin, View):
|
| 47 |
def get(self, request, pk, *args, **kwargs):
|
| 48 |
post = Post.objects.get(pk=pk)
|
| 49 |
form = CommentForm()
|
| 50 |
-
|
| 51 |
comments = Comment.objects.filter(post=post).order_by('-created_on')
|
| 52 |
|
| 53 |
context = {
|
|
@@ -57,6 +46,7 @@ class PostDetailView(LoginRequiredMixin, View):
|
|
| 57 |
}
|
| 58 |
|
| 59 |
return render(request, 'social/post_detail.html', context)
|
|
|
|
| 60 |
def post(self, request, pk, *args, **kwargs):
|
| 61 |
post = Post.objects.get(pk=pk)
|
| 62 |
form = CommentForm(request.POST)
|
|
@@ -66,7 +56,7 @@ class PostDetailView(LoginRequiredMixin, View):
|
|
| 66 |
new_comment.author = request.user
|
| 67 |
new_comment.post = post
|
| 68 |
new_comment.save()
|
| 69 |
-
|
| 70 |
comments = Comment.objects.filter(post=post).order_by('-created_on')
|
| 71 |
|
| 72 |
context = {
|
|
@@ -81,11 +71,11 @@ class PostEditView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
|
|
| 81 |
model = Post
|
| 82 |
fields = ['body']
|
| 83 |
template_name = 'social/post_edit.html'
|
| 84 |
-
|
| 85 |
def get_success_url(self):
|
| 86 |
pk = self.kwargs['pk']
|
| 87 |
return reverse_lazy('post-detail', kwargs={'pk': pk})
|
| 88 |
-
|
| 89 |
def test_func(self):
|
| 90 |
post = self.get_object()
|
| 91 |
return self.request.user == post.author
|
|
@@ -108,135 +98,5 @@ class CommentDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
|
|
| 108 |
return reverse_lazy('post-detail', kwargs={'pk': pk})
|
| 109 |
|
| 110 |
def test_func(self):
|
| 111 |
-
|
| 112 |
-
return self.request.user ==
|
| 113 |
-
|
| 114 |
-
class ProfileView(View):
|
| 115 |
-
def get(self, request, pk, *args, **kwargs):
|
| 116 |
-
profile = UserProfile.objects.get(pk=pk)
|
| 117 |
-
user = profile.user
|
| 118 |
-
posts = Post.objects.filter(author=user).order_by('-created_on')
|
| 119 |
-
|
| 120 |
-
followers = profile.followers.all()
|
| 121 |
-
|
| 122 |
-
if len(followers) == 0:
|
| 123 |
-
is_following = False
|
| 124 |
-
|
| 125 |
-
for follower in followers:
|
| 126 |
-
if follower == request.user:
|
| 127 |
-
is_following = True
|
| 128 |
-
break
|
| 129 |
-
else:
|
| 130 |
-
is_following = False
|
| 131 |
-
|
| 132 |
-
number_of_followers = len(followers)
|
| 133 |
-
|
| 134 |
-
context = {
|
| 135 |
-
'user': user,
|
| 136 |
-
'profile': profile,
|
| 137 |
-
'posts': posts,
|
| 138 |
-
'number_of_followers': number_of_followers,
|
| 139 |
-
'is_following': is_following,
|
| 140 |
-
}
|
| 141 |
-
|
| 142 |
-
return render(request, 'social/profile.html', context)
|
| 143 |
-
|
| 144 |
-
class ProfileEditView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
|
| 145 |
-
model = UserProfile
|
| 146 |
-
fields = ['name', 'bio', 'birth_date', 'location', 'picture']
|
| 147 |
-
template_name = 'social/profile_edit.html'
|
| 148 |
-
|
| 149 |
-
def get_success_url(self):
|
| 150 |
-
pk = self.kwargs['pk']
|
| 151 |
-
return reverse_lazy('profile', kwargs={'pk': pk})
|
| 152 |
-
|
| 153 |
-
def test_func(self):
|
| 154 |
-
profile = self.get_object()
|
| 155 |
-
return self.request.user == profile.user
|
| 156 |
-
|
| 157 |
-
class AddFollower(LoginRequiredMixin, View):
|
| 158 |
-
def post(self, request, pk, *args, **kwargs):
|
| 159 |
-
profile = UserProfile.objects.get(pk=pk)
|
| 160 |
-
profile.followers.add(request.user)
|
| 161 |
-
|
| 162 |
-
return redirect('profile', pk=profile.pk)
|
| 163 |
-
|
| 164 |
-
class RemoveFollower(LoginRequiredMixin, View):
|
| 165 |
-
def post(self, request, pk, *args, **kwargs):
|
| 166 |
-
profile = UserProfile.objects.get(pk=pk)
|
| 167 |
-
profile.followers.remove(request.user)
|
| 168 |
-
|
| 169 |
-
return redirect('profile', pk=profile.pk)
|
| 170 |
-
|
| 171 |
-
class AddLike(LoginRequiredMixin, View):
|
| 172 |
-
def post(self, request, pk, *args, **kwargs):
|
| 173 |
-
post = Post.objects.get(pk=pk)
|
| 174 |
-
|
| 175 |
-
is_dislike = False
|
| 176 |
-
|
| 177 |
-
for dislike in post.dislikes.all():
|
| 178 |
-
if dislike == request.user:
|
| 179 |
-
is_dislike = True
|
| 180 |
-
break
|
| 181 |
-
|
| 182 |
-
if is_dislike:
|
| 183 |
-
post.dislikes.remove(request.user)
|
| 184 |
-
|
| 185 |
-
is_like = False
|
| 186 |
-
|
| 187 |
-
for like in post.likes.all():
|
| 188 |
-
if like == request.user:
|
| 189 |
-
is_like = True
|
| 190 |
-
break
|
| 191 |
-
|
| 192 |
-
if not is_like:
|
| 193 |
-
post.likes.add(request.user)
|
| 194 |
-
|
| 195 |
-
if is_like:
|
| 196 |
-
post.likes.remove(request.user)
|
| 197 |
-
|
| 198 |
-
next = request.POST.get('next', '/')
|
| 199 |
-
return HttpResponseRedirect(next)
|
| 200 |
-
|
| 201 |
-
class AddDislike(LoginRequiredMixin, View):
|
| 202 |
-
def post(self, request, pk, *args, **kwargs):
|
| 203 |
-
post = Post.objects.get(pk=pk)
|
| 204 |
-
|
| 205 |
-
is_like = False
|
| 206 |
-
|
| 207 |
-
for like in post.likes.all():
|
| 208 |
-
if like == request.user:
|
| 209 |
-
is_like = True
|
| 210 |
-
break
|
| 211 |
-
|
| 212 |
-
if is_like:
|
| 213 |
-
post.likes.remove(request.user)
|
| 214 |
-
|
| 215 |
-
is_dislike = False
|
| 216 |
-
|
| 217 |
-
for dislike in post.dislikes.all():
|
| 218 |
-
if dislike == request.user:
|
| 219 |
-
is_dislike = True
|
| 220 |
-
break
|
| 221 |
-
|
| 222 |
-
if not is_dislike:
|
| 223 |
-
post.dislikes.add(request.user)
|
| 224 |
-
|
| 225 |
-
if is_dislike:
|
| 226 |
-
post.dislikes.remove(request.user)
|
| 227 |
-
|
| 228 |
-
next = request.POST.get('next', '/')
|
| 229 |
-
return HttpResponseRedirect(next)
|
| 230 |
-
|
| 231 |
-
class UserSearch(View):
|
| 232 |
-
def get(self, request, *args, **kwargs):
|
| 233 |
-
query = self.request.GET.get('query')
|
| 234 |
-
profile_list = UserProfile.objects.filter(
|
| 235 |
-
Q(user__username__icontains=query)
|
| 236 |
-
)
|
| 237 |
-
|
| 238 |
-
context = {
|
| 239 |
-
'profile_list': profile_list,
|
| 240 |
-
}
|
| 241 |
-
|
| 242 |
-
return render(request, 'social/search.html', context)
|
|
|
|
| 1 |
+
from django.shortcuts import render
|
|
|
|
| 2 |
from django.urls import reverse_lazy
|
|
|
|
| 3 |
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
|
| 4 |
from django.views import View
|
|
|
|
|
|
|
| 5 |
from django.views.generic.edit import UpdateView, DeleteView
|
| 6 |
+
from .models import Post, Comment
|
| 7 |
+
from .forms import PostForm, CommentForm
|
| 8 |
|
| 9 |
|
| 10 |
class PostListView(LoginRequiredMixin, View):
|
| 11 |
def get(self, request, *args, **kwargs):
|
| 12 |
+
posts = Post.objects.all().order_by('-created_on')
|
|
|
|
|
|
|
|
|
|
| 13 |
form = PostForm()
|
| 14 |
|
| 15 |
context = {
|
| 16 |
'post_list': posts,
|
| 17 |
'form': form,
|
| 18 |
}
|
|
|
|
| 19 |
return render(request, 'social/post_list.html', context)
|
| 20 |
|
| 21 |
def post(self, request, *args, **kwargs):
|
| 22 |
+
posts = Post.objects.all().order_by('-created_on')
|
|
|
|
|
|
|
|
|
|
| 23 |
form = PostForm(request.POST)
|
| 24 |
|
| 25 |
if form.is_valid():
|
|
|
|
| 31 |
'post_list': posts,
|
| 32 |
'form': form,
|
| 33 |
}
|
|
|
|
| 34 |
return render(request, 'social/post_list.html', context)
|
| 35 |
|
| 36 |
class PostDetailView(LoginRequiredMixin, View):
|
| 37 |
def get(self, request, pk, *args, **kwargs):
|
| 38 |
post = Post.objects.get(pk=pk)
|
| 39 |
form = CommentForm()
|
|
|
|
| 40 |
comments = Comment.objects.filter(post=post).order_by('-created_on')
|
| 41 |
|
| 42 |
context = {
|
|
|
|
| 46 |
}
|
| 47 |
|
| 48 |
return render(request, 'social/post_detail.html', context)
|
| 49 |
+
|
| 50 |
def post(self, request, pk, *args, **kwargs):
|
| 51 |
post = Post.objects.get(pk=pk)
|
| 52 |
form = CommentForm(request.POST)
|
|
|
|
| 56 |
new_comment.author = request.user
|
| 57 |
new_comment.post = post
|
| 58 |
new_comment.save()
|
| 59 |
+
|
| 60 |
comments = Comment.objects.filter(post=post).order_by('-created_on')
|
| 61 |
|
| 62 |
context = {
|
|
|
|
| 71 |
model = Post
|
| 72 |
fields = ['body']
|
| 73 |
template_name = 'social/post_edit.html'
|
| 74 |
+
|
| 75 |
def get_success_url(self):
|
| 76 |
pk = self.kwargs['pk']
|
| 77 |
return reverse_lazy('post-detail', kwargs={'pk': pk})
|
| 78 |
+
|
| 79 |
def test_func(self):
|
| 80 |
post = self.get_object()
|
| 81 |
return self.request.user == post.author
|
|
|
|
| 98 |
return reverse_lazy('post-detail', kwargs={'pk': pk})
|
| 99 |
|
| 100 |
def test_func(self):
|
| 101 |
+
comment = self.get_object()
|
| 102 |
+
return self.request.user == comment.author
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|