Cannot automatically select a foreign key value on save

I’m trying to override the save method on a model so that is can compare the domain contained in a link being added to the main model and select that domain from a foreign key model, to automatically save that domain as the foreign key value without me having to manually select it in the Django Admin interace.

However, I get Cannot assign ... must be an instance errors even though the expected value is already in the foreign key table, for example:

ValueError: Cannot assign "'www.theguardian.com'": "Link.source" must be a "Source" instance.

I’m not sure if it is impossible to automate this in a model method, but here are my models:

from django.db import models

from bs4 import BeautifulSoup  # for scraping
from urllib.parse import urlparse
import requests  # for scraping

class Source(models.Model):
    netloc = models.CharField(max_length=50, unique=True)

    class Meta:
        ordering = ['netloc']

    def __str__(self):
        return self.netloc

class Link(models.Model):

    url = models.URLField(max_length=200, unique=True, verbose_name='URL')

    title = models.CharField(max_length=120, unique=True, blank=True,
        help_text = 'Set manually if scraped title is not suitable')

    source = models.ForeignKey('Source',
        on_delete=models.PROTECT, to_field='netloc', default='000.example.org',
    )
    ...

    def get_scraped_title(self):
        reqs = requests.get(self.url)
        soup = BeautifulSoup(reqs.text, 'html.parser')
        return soup.title.get_text()

    def get_netloc(self):
        return urlparse(self.url).netloc

    def save(self, *args, **kwargs):

        if not self.title:
            self.title = self.get_scraped_title()

        self.source = self.get_netloc()

        super(Link, self).save(*args, **kwargs)

In the ORM, this is a reference to the Source object, not the referenced key.

If you wish to use the key field directly, you use the _id suffix on the ForeignKey field.
e.g. self.source_id = self.get_netloc()

See the docs for ForeignKey and Field lookups for more information on this.

Ah I knew I was asking a dumb question … I was thinking that wouldn’t work because I’d made my ForeignKey field use a CharField as to_field and I thought I would have to match that in my model method.

Thank you!