diff --git a/config/settings/base.py b/config/settings/base.py index 16c6413..0439961 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -53,7 +53,7 @@ ROOT_URLCONF = "flangr.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [], + "DIRS": ["flangr/templates"], "APP_DIRS": True, "OPTIONS": { "context_processors": [ @@ -111,3 +111,5 @@ STATIC_URL = "static/" DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" MEDIA_URL = "media/" + +AUTH_USER_MODEL = "auth.User" diff --git a/flangr/posts/admin.py b/flangr/posts/admin.py index 8c38f3f..a0e1a5f 100644 --- a/flangr/posts/admin.py +++ b/flangr/posts/admin.py @@ -1,3 +1,9 @@ from django.contrib import admin +from .models import Post, Collection, Comment + # Register your models here. + +admin.site.register(Post) +admin.site.register(Collection) +admin.site.register(Comment) diff --git a/flangr/posts/forms.py b/flangr/posts/forms.py new file mode 100644 index 0000000..726a1c4 --- /dev/null +++ b/flangr/posts/forms.py @@ -0,0 +1,3 @@ +from django.forms import ModelForm + +from .models import Comment diff --git a/flangr/posts/migrations/0001_initial.py b/flangr/posts/migrations/0001_initial.py index 7dfef44..ff728d5 100644 --- a/flangr/posts/migrations/0001_initial.py +++ b/flangr/posts/migrations/0001_initial.py @@ -1,13 +1,17 @@ -# Generated by Django 4.0.5 on 2022-07-03 21:35 +# Generated by Django 4.0.5 on 2022-07-04 20:55 +from django.conf import settings from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): initial = True - dependencies = [] + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] operations = [ migrations.CreateModel( @@ -25,8 +29,71 @@ class Migration(migrations.Migration): ("img", models.ImageField(upload_to="posts/%Y/%m")), ("posted", models.DateTimeField(auto_now_add=True)), ("public", models.BooleanField(default=False)), + ("title", models.CharField(max_length=255, null=True)), + ("body", models.TextField(null=True)), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="Comment", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("comment", models.CharField(max_length=255)), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="posts.post" + ), + ), + ( + "user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="Collection", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), ("title", models.CharField(max_length=255)), - ("body", models.TextField()), + ("description", models.TextField()), + ( + "posts", + models.ManyToManyField(related_name="collections", to="posts.post"), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), ], ), ] diff --git a/flangr/posts/migrations/0002_alter_comment_post_alter_post_img.py b/flangr/posts/migrations/0002_alter_comment_post_alter_post_img.py new file mode 100644 index 0000000..3548356 --- /dev/null +++ b/flangr/posts/migrations/0002_alter_comment_post_alter_post_img.py @@ -0,0 +1,29 @@ +# Generated by Django 4.0.5 on 2022-07-04 21:26 + +from django.db import migrations, models +import django.db.models.deletion +import flangr.posts.models + + +class Migration(migrations.Migration): + + dependencies = [ + ("posts", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="comment", + name="post", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="comments", + to="posts.post", + ), + ), + migrations.AlterField( + model_name="post", + name="img", + field=models.ImageField(upload_to=flangr.posts.models.get_img_location), + ), + ] diff --git a/flangr/posts/models.py b/flangr/posts/models.py index 0c1c4fa..fa22ba2 100644 --- a/flangr/posts/models.py +++ b/flangr/posts/models.py @@ -1,15 +1,49 @@ +import uuid + from django.db import models +from django.conf import settings + # Create your models here. +def get_img_location(instance, filename): + uid = uuid.uuid4().hex + return f"{uid[0:2]}/{uid[2:]}" + + class Post(models.Model): - img = models.ImageField(upload_to="posts/%Y/%m") + img = models.ImageField(upload_to=get_img_location) posted = models.DateTimeField(auto_now_add=True) public = models.BooleanField(default=False) - title = models.CharField(max_length=255) - body = models.TextField() + title = models.CharField(max_length=255, null=True) + body = models.TextField(null=True) + + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) def __str__(self): return f"Post: {self.title} at {self.posted.strftime('%Y-%m-%d %H:%S')}" + + +class Collection(models.Model): + title = models.CharField(max_length=255) + description = models.TextField() + + posts = models.ManyToManyField("Post", related_name="collections") + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + + def __str__(self): + return f"Collection: {self.title}" + + +class Comment(models.Model): + post = models.ForeignKey("Post", on_delete=models.CASCADE, related_name="comments") + comment = models.CharField(max_length=255) + + user = models.ForeignKey( + settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True + ) + + def __str__(self): + return f"Comment by {self.user} on {self.post}" diff --git a/flangr/posts/tests.py b/flangr/posts/tests.py index d0d72fa..94ded9b 100644 --- a/flangr/posts/tests.py +++ b/flangr/posts/tests.py @@ -3,24 +3,29 @@ import os from django.test import TestCase from django.core.files import File -from .models import Post +from .models import Post, Collection # Create your tests here. -class TestPostModelTests(TestCase): - def test_can_create_model(self): +class TestModelTests(TestCase): + def setUp(self): with open( os.path.join(os.path.dirname(__file__), "test_data", "test_img.png"), mode="rb", ) as f: - try: - p = Post.objects.create( - img=File(f, "somefile.png"), - title="Foobar", - body="Some file", - ) + self.post = Post.objects.create( + img=File(f, "somefile.png"), + title="Foobar", + body="Some file", + ) - self.assertIn("Foobar", str(p)) - finally: - p.img.delete() + def tearDown(self): + self.post.img.delete() + + def test_post_has_sensible_str(self): + self.assertIn("Foobar", str(self.post)) + + def test_collection_has_sensible_str(self): + col = Collection.objects.create(title="A collection", description="foobar") + self.assertIn("A collection", str(col)) diff --git a/flangr/posts/urls.py b/flangr/posts/urls.py new file mode 100644 index 0000000..6bd7575 --- /dev/null +++ b/flangr/posts/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path("post/", views.PostDetailView.as_view()), + path("post//comments", views.AddCommentView.as_view()), +] diff --git a/flangr/posts/views.py b/flangr/posts/views.py index 91ea44a..5fa1d08 100644 --- a/flangr/posts/views.py +++ b/flangr/posts/views.py @@ -1,3 +1,17 @@ -from django.shortcuts import render +from django.views.generic import DetailView +from django.forms import modelform_factory # Create your views here. + +from .models import Post, Comment + + +class PostDetailView(DetailView): + model = Post + + def get_context_data(self, **kwargs): + context = { + "add_comment_form": modelform_factory(Comment, fields=("comment",)), + **kwargs, + } + return super().get_context_data(**context) diff --git a/flangr/templates/posts/post_detail.html b/flangr/templates/posts/post_detail.html new file mode 100644 index 0000000..d44eb00 --- /dev/null +++ b/flangr/templates/posts/post_detail.html @@ -0,0 +1,20 @@ + + {% if object.title %} +

{{ object.title }}

+ {% else %} +

{{ object.user.username }}

+ {% endif %} + +

Comments

+ +
+ {% csrf_token %} + {{ add_comment_form }} + +
+ diff --git a/flangr/urls.py b/flangr/urls.py index 27e300e..13f018a 100644 --- a/flangr/urls.py +++ b/flangr/urls.py @@ -14,8 +14,15 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path +from django.urls import path, include + +from django.conf import settings +from django.conf.urls.static import static urlpatterns = [ path("admin/", admin.site.urls), + path("posts/", include("flangr.posts.urls")), ] + +if settings.DEBUG: + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)