Django中如何link两个objects保存在不同的地方

How to link two objects saved in different places in Django

我正在尝试实现类似于 Facebook 正在做的事情:在博客 post 中,当您 post 对文章 link 时,它会自动获取标签以获取图像、标题和描述,然后将其呈现在页面上。

在起草 post 时,我使用 websocket 感谢 Django Channels 将 link 从前端发送到后端以通过 Beautiful Soup 检索不同的元素。然后我把它们送回前台显示。

当我想将 post 与共享的 url 元素一起保存时,问题就出现了。为了管理 post 创建,我使用了 CBV PostCreate。我可以在消费者中保存共享的 url 元素。但是这两个 object 没有 linked,我不知道如何获取 SharedArticle object id 并将其与 post 一起保存。

我有两个模型:PostSharedArticle

这是我的 consumer.py

class UrlConsumer(AsyncConsumer):
    async def websocket_connect(self, event):
        chat_room = "shared_url"
        self.chat_room = chat_room
        await self.channel_layer.group_add(
            chat_room,
            self.channel_name
        )
        await self.send({
            "type": "websocket.accept"
        })


    async def websocket_receive(self, event):
        print("receive", event)
        page = urlopen(event['text'])
        soup = BeautifulSoup(page, "html.parser")
        title = soup.find('meta', property='og:title')
        img = soup.find('meta', property='og:image')
        description = soup.find('meta', property='og:description')
        article = {
            'title':title['content'],
            'img':img['content'],
            'description': description['content'],
            'url': event['text']
        }
        await self.channel_layer.group_send(
                self.chat_room,
                {
                    "type": "chat_message",
                    "text": json.dumps(article)
                }
            )

        await self.create_shared_article(
                        article['title'],
                        article['description'],
                        article['img'],
                        article['url'])

这是我的 views.py

class PostCreate(UserPassesTestMixin, CreateView):
    model = Post
    fields = ['title', 'content', 'draft', 'publish', 'category']

    def test_func(self):
        return self.request.user.is_superuser

    def form_valid(self, form):
        form.instance.user = self.request.user
        content = form.instance.content
        title = form.instance.title

        send_email(title, content)

        return super().form_valid(form)

    def get_form(self):
        form = super().get_form()
        form.fields['content'].widget = PagedownWidget(show_preview=False)
        form.fields['publish'].widget = SelectDateWidget()
        return form

还有我的models.py

class ArticleShared(models.Model):
    title = models.CharField(max_length=250)
    description = models.CharField(max_length=500)
    url = models.CharField(max_length=250)
    img = models.CharField(max_length=250)

    def __str__(self):
        return self.title


class Post(models.Model):
    user = models.ForeignKey(User,
                             null=True,
                             default=1,
                             on_delete=models.SET_NULL
                             )
    title = models.CharField(max_length=250)
    content = models.TextField()
    draft = models.BooleanField(default=False)
    publish = models.DateTimeField(auto_now=False,
                                   auto_now_add=False,
                                   default=now())
    created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
    category = models.ForeignKey(Category,
                                 null=True,
                                 on_delete=models.SET_NULL)
    article_shared = models.ForeignKey(ArticleShared,
                                 null=True,
                                 on_delete=models.SET_NULL)

知道如何实现吗?

发现ArticleShared后需要通过频道传回主键。为此,您需要更改 create_shared_article 和 group_send.

的顺序
async def websocket_receive(self, event):
   # .. look up data
   article_shared = self.create_shared_article(...)
   await self.channel_layer.group_send(
      self.chat_room,
      {
         "type": "chat_message",
         "text": json.dumps(
            { "article" : article, "pk" : article_shared.pk }
         )
      }
   )

然后,在您的前端代码中,您可以在 article_shared 的表单字段中插入 "pk",然后再保存 Post。