Skip to content

Commit

Permalink
Merge pull request #34 from matagus/use-django-better-way
Browse files Browse the repository at this point in the history
Making better use of Django's generic relations
  • Loading branch information
matagus authored Feb 10, 2024
2 parents afc60bb + fd27204 commit ba409e4
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 29 deletions.
10 changes: 4 additions & 6 deletions generic_links/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,18 @@ class Meta:
model = GenericLink
fields = ("title", "url", "description", "is_external")

def __init__(self, user, content_type, object_id, *args, **kwargs):
def __init__(self, content_object, user, *args, **kwargs):
self.content_object = content_object
self.user = user
self.content_type = content_type
self.object_id = object_id
super().__init__(*args, **kwargs)

def save(self, *args, **kwargs):
self.instance = GenericLink.objects.create(
content_type=self.content_type,
object_id=self.object_id,
content_object=self.content_object,
url=self.cleaned_data["url"].strip(),
title=self.cleaned_data["title"],
user=self.user,
is_external=self.cleaned_data["is_external"],
)

self.instance.save()
return self.instance
25 changes: 25 additions & 0 deletions generic_links/migrations/0002_alter_genericlink_id_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 5.0.1 on 2024-02-10 15:06

from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("contenttypes", "0002_remove_content_type_name"),
("generic_links", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.AlterField(
model_name="genericlink",
name="id",
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID"),
),
migrations.AddIndex(
model_name="genericlink",
index=models.Index(fields=["content_type", "object_id"], name="generic_lin_content_569ecc_idx"),
),
]
5 changes: 4 additions & 1 deletion generic_links/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class GenericLink(models.Model):

content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField(db_index=True)
content_object = GenericForeignKey()
content_object = GenericForeignKey("content_type", "object_id")

url = models.URLField()
title = models.CharField(max_length=200)
Expand All @@ -29,6 +29,9 @@ class Meta:
ordering = ("-created_at",)
verbose_name = _("Generic Link")
verbose_name_plural = _("Generic Links")
indexes = [
models.Index(fields=["content_type", "object_id"]),
]

def __str__(self):
return f"{self.title} :: {self.url}"
15 changes: 6 additions & 9 deletions tests/test_forms.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase

from generic_links.forms import AddLinkForm


class AddFormTest(TestCase):
def setUp(self):
content_type = ContentType.objects.get_for_model(User)
self.initial_kwargs = dict(user=None, object_id=1, content_type=content_type)
self.content_object = User.objects.create_user(username="test", password="test")
self.initial_args = (self.content_object, None)

def test_add_form_without_data(self):
form = AddLinkForm(**self.initial_kwargs)
form = AddLinkForm(*self.initial_args)
self.assertFalse(form.is_valid())

def test_add_form_with_incomplete_data(self):
form = AddLinkForm(data={"url": "http://www.example.com"}, **self.initial_kwargs)
form = AddLinkForm(*self.initial_args, data={"url": "http://www.example.com"})
self.assertFalse(form.is_valid())

def test_add_form_with_complete_data(self):
form = AddLinkForm(data={"url": "http://www.example.com", "title": "Example"}, **self.initial_kwargs)
form = AddLinkForm(*self.initial_args, data={"url": "http://www.example.com", "title": "Example"})
self.assertTrue(form.is_valid())

new_link = form.save()
print(new_link.content_object)
self.assertEqual(new_link.url, "http://www.example.com")
self.assertEqual(new_link.title, "Example")
self.assertEqual(new_link.user, None)
self.assertEqual(new_link.object_id, 1)
self.assertEqual(new_link.content_type_id, self.initial_kwargs["content_type"].id)
self.assertEqual(new_link.content_object, self.content_object)
self.assertEqual(new_link.is_external, False)
5 changes: 1 addition & 4 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase

from generic_links.models import GenericLink
Expand All @@ -10,14 +9,12 @@
class ModelTest(TestCase):
def test_str(self):
user = User.objects.create(username="Test User")
content_type = ContentType.objects.get_for_model(User)

link = GenericLink.objects.create(
title="Test Title",
url="https://www.test.com",
description="Test Description",
content_type=content_type,
object_id=user.id,
content_object=user,
)

self.assertEqual(str(link), f"{link.title} :: {link.url}")
15 changes: 6 additions & 9 deletions tests/test_templatetags.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.template import Context, Template
from django.test import TestCase

Expand All @@ -12,29 +11,27 @@ class TemplateTagTestCase(TestCase):
"""

def setUp(self):
content_type = ContentType.objects.get_for_model(User)

self.user1 = User.objects.create(username="test_user")

self.link1 = GenericLink.objects.create(
url="https://example.com/path/to/this-thing/",
content_type=content_type,
object_id=self.user1.id,
content_object=self.user1,
)
self.link1.save()

self.link2 = GenericLink.objects.create(
url="https://example.com/path/to/other-thing/",
content_type=content_type,
object_id=self.user1.id,
content_object=self.user1,
)
self.link2.save()

self.user2 = User.objects.create(username="test_user2")

self.link3 = GenericLink.objects.create(
url="https://example.com/foobar/",
content_type=content_type,
object_id=self.user2.id,
content_object=self.user2,
)
self.link3.save()

def test_get_links_for(self):
"""
Expand Down

0 comments on commit ba409e4

Please sign in to comment.