Django. Объект типа Url не является сериализуемым в JSON

Я пишу парсер для сайта. У меня есть 2 модели: Url (id и url сайта) и News (все данные, которые будут разобраны)

Я сделал форму, которая позволяет пользователям вводить ссылку сайта, которая автоматически сохраняется в db. А также у меня есть сигнал, который начинает парсить данные, как только экземпляр Url сохраняется. Но дело в том, что когда я вызываю функцию hackernews_rss, которая разбирает данные, я получаю ошибку

kombu.exceptions.EncodeError: Object of type Url is not JSON serializable

Я не знаю, как это исправить, так как для сохранения всех результатов парсинга мне необходимо иметь экземпляр Url из-за OneToManeRelation

модели:

class Url(models.Model):
    link = models.CharField(
        max_length=200,
        blank=True
    )
    def get_absolute_url(self):
        return f'/parser/search/'

class News(models.Model):
    domain = models.CharField(max_length=200)
    link_id = models.ForeignKey(Url, on_delete=models.CASCADE)
    link = models.CharField(max_length=200, blank=True)
    create_date = models.DateTimeField()
    update_date = models.DateTimeField()
    country = models.CharField(max_length=200, null=True)
    is_dead = models.BooleanField()
    a = models.CharField(max_length=200, null=True)
    ns = models.CharField(max_length=200, null=True)
    cname = models.CharField(max_length=200, null=True)
    mx = models.CharField(max_length=200, null=True)
    txt = models.CharField(max_length=200, null=True)

задачи:

@shared_task(serializer='json')
def save_function(article_list):
    print('starting')
    new_count = 0

    for article in article_list:
        try:
            print(article['link_id'])
            News.objects.create(
                link=article['link'],
                domain=article['domain'],
                create_date=article['create_date'],
                update_date=article['update_date'],
                country=article['country'],
                is_dead=article['is_dead'],
                a=article['a'],
                ns=article['ns'],
                cname=article['cname'],
                mx=article['mx'],
                txt=article['txt'],
                link_id = article['link_id']
            )
            new_count += 1
        except Exception as e:
            print('failed at latest_article is none')
            print(e)
            break
    return print('finished')


@shared_task
def hackernews_rss(url, url_id, instance):
    print(url, url_id)
    article_list = []
    try:
        print('Starting the Scrapping tool')
        r = requests.get(url)
        soup = BeautifulSoup(r.content, features='lxml')
        container = soup.select('a')
        url_storage = []
        for block in container:
            try:
                url1 = block.get('href')
                if url1.startswith('http'):
                    url_storage.append(url1)
            except:
                continue
        for link in url_storage:
            r = requests.get(f'https://api.domainsdb.info/v1/domains/search?domain={link}')
            data = r.text

            parse_json = json.loads(data)

            for block in parse_json['domains']:
                domain = block['domain']
                create_date = block['create_date']
                update_date = block['update_date']
                country = block['country']
                is_dead = block['isDead']
                a = block['A']
                ns = block['NS']
                cname = block['CNAME']
                mx = block['MX']
                txt = block['TXT']
                article = {
                    'domain': domain,
                    'link': link,
                    'create_date': create_date,
                    'update_date': update_date,
                    'country': country,
                    'is_dead': is_dead,
                    'a': a,
                    'ns': ns,
                    'cname': cname,
                    'mx': mx,
                    'txt': txt,
                    'link_id': url_id
                }

                article_list.append(article)
            print('Finished scraping the articles')
            return save_function(article_list)
    except Exception as e:
        print('The scraping job failed. See exception:')
        print(e)

сигналы:


@receiver(post_save, sender=Url)
def notify_subscribers(sender, instance, created, **kwargs):
    if created:
        url_instance = instance.link
        url_id = instance.id
        hackernews_rss.delay(url_instance, url_id, instance)

просмотров:


class HomePageView(generic.ListView):
    template_name = 'home.html'
    context_object_name = 'articles'
    paginate_by = 7
    queryset = News.objects.order_by('create_date')
    form_class = ParserForm

    def get_queryset(self):
        queryset = super().get_queryset()
        return ParserFilter(self.request.GET, queryset=queryset).qs

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['filter'] = ParserFilter(self.request.GET, queryset=self.get_queryset())
        return context


class UrlCreateView(generic.CreateView):
    template_name = 'url_create.html'
    form_class = CreateForm

    model = Url

Формы:

class CreateForm(ModelForm):

    class Meta:
        model = Url
        fields = ['link']

Должен признаться, что раньше я не указывал экземпляр hackernews_rss в качестве аргумента. Я хотел создать отношение по link_id: 'link_id': url_idl_. Но celery выдал следующую ошибку:

 Cannot assign "15": "News.link_id" must be a "Url" instance.
Вернуться на верх