Which inheritance to cover different types of Link

Kindly asking to help me with this: How to properly design it ? Which inheritance type to use ? How would you do it ?

I have a model Link where I want to save all links which will then be used in application.
There are several types of Link:

  • external link which is URL (for example: “https://example.com”)
  • internal link represented by view (for example: “myapp.index_page”)
  • relative link (for example: “…/contact-me”)
  • etc.

Each of this links needs different href represantion (different HTML code).

My idea is to have a parent model Link and 3 child models: ExternalLink, InternalLink, RelativeLink.
When creating links, I should be able to separately create only child model instances.
When using links, I don’t care which type of link it is, so I would like to do ForeignKey to parent model to see all instances together.

class Link(models.Model):
    text = models.CharField(max_length=100)
	icon = models.CharField(...)

class ExternalLink(Link):
    url = URLField()

class InternalLink(Link):
    view = models.CharField(choices=...)

class RelativeLink(Link):
    address = models.CharField(...)

class Page(models.Model):
    text = models.CharField(max_length=100)
	link = models.ForeignKey(Link)

Regarding HTML represantion, ideally each child would have its own template and would render itself depending on the link type.

<opinion>
I don’t think I would ever consider this as an approach that I would use for modeling this data.

From a data model perspective, a link is just some text. There may be attributes associated with that text, but at its core, it’s still just a string representing a resource.

Those differences in how they are to be validated and rendered could be encapsulated as an attribute associated with the type of link.

In other words, I’d be looking at something like this:

class Link(models.Model):
    text = models.CharField(max_length=100)
    url = models.CharField(max_length=1000)
    icon = models.CharField(...)
    link_type = models.ForeignKey(UrlType, ...)

class UrlType(models.Model):
    template_name = models.CharField(...)
    <other attributes or behaviors as needed>
    ...

Everything else flows from that as a starting point.
</opinion>

2 Likes

@KenWhitesell Wow, really nice simplification… Only problem I see is that editor user would have to correctly set link_type.