【问题标题】:Save additional data to Django database将附加数据保存到 Django 数据库
【发布时间】:2017-01-01 22:42:00
【问题描述】:

我正在使用 Django 频道,我希望能够将其他字段与帖子的 json 数据一起保存到数据库中。

我的Postmie 模型中有一个外键,它指向我的用户模型中的email 字段。 Postmie 是负责将帖子保存到数据库的模型。外键创建一个名为email_id 的字段。当我将帖子保存到数据库时,我还想获取发布帖子的用户的电子邮件并将其保存在数据库中。我该怎么做呢?我没有使用 Django 表单。

我的 Postmie 模型与 Django Channels 教程 Post 找到的 here 中的模型相同,唯一的区别是我的模型有一个额外的外键指向我的用户模型中的电子邮件字段。

email=request.user.email 不起作用。我正在考虑将电子邮件放在隐藏字段中,但这对我来说似乎不安全。

我使用的方法实际上与找到hereconsumers.py 的Django Channels 教程中的方法相同。一切正常,但我无法在数据库中输入帖子的其他字段。

def save_post(message, slug, request):
    """
    Saves vew post to the database.
    """
    post = json.loads(message['text'])['post']
    email = request.user.email
    feed = Feed.objects.get(slug=slug)
    Postmie.objects.create(feed=feed, body=post email_id=email)

Postmie 模型:

@python_2_unicode_compatible
class Postmie(models.Model):
    # Link back to the main blog.
    feed = models.ForeignKey(Feed, related_name="postmie")
    email = models.ForeignKey(Usermie,
                              to_field="email",
                              related_name="postmie_email",  max_length=50)
    subject = models.CharField(max_length=50)
    classs = models.CharField(max_length=50, null=True, blank=True)
    subclass = models.CharField(max_length=50, null=True, blank=True)
    title = models.CharField(max_length=60, null=True, blank=True)
    body = models.TextField()
    date_created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return "#%i: %s" % (self.id, self.body_intro())

    def post_email(self):
        return self.email

    def post_subject(self):
        return self.subject

    def post_datetime(self):
        return self.datetime

    def get_absolute_url(self):
        """
        Returns the URL to view the liveblog.
        """
        return "/feed/%s/" % self.slug

    def body_intro(self):
        """
        Short first part of the body to show in the admin or other compressed
        views to give you some idea of what this is.
        """
        return self.body[:50]

    def html_body(self):
        """
        Returns the rendered HTML body to show to browsers.
        You could change this method to instead render using RST/Markdown,
        or make it pass through HTML directly (but marked safe).
        """
        return linebreaks_filter(self.body)

    def send_notification(self):
        """
        Sends a notification to everyone in our Liveblog's group with our
        content.
        """
        # Make the payload of the notification. We'll JSONify this, so it has
        # to be simple types, which is why we handle the datetime here.
        notification = {
            "id": self.id,
            "html": self.html_body(),
            "date_created": self.date_created.strftime("%a %d %b %Y %H:%M"),
        }
        # Encode and send that message to the whole channels Group for our
        # feed. Note how you can send to a channel or Group from any part
        # of Django, not just inside a consumer.
        Group(self.feed.group_name).send({
            # WebSocket text frame, with JSON content
            "text": json.dumps(notification),
        })

    def save(self, *args, **kwargs):
        """
        Hooking send_notification into the save of the object as I'm not
        the biggest fan of signals.
        """
        result = super(Postmie, self).save(*args, **kwargs)
        self.send_notification()
        return result

【问题讨论】:

  • “外键创建一个名为 email_id 的字段”是什么意思。你能给我们展示一下 Postmie 的模型吗?可以使用用户作为外键吗?
  • 我添加了Postmie 模型。我创建的外键称为email。但是在数据库中创建的列名为email_id。与feed 字段相同,数据库中的列名称为field_id。我认为这是 Django 的做事方式。
  • 这里,问题是email_id是外键email对象的id。您可以创建一个 post_save 信号,该信号将创建电子邮件对象,并将该对象与其关联。
  • 是的,它是父表的 id,但是我使用 to_field 将其更改为实际的电子邮件。谢谢@karthikr 我会试试你说的post_save

标签: django django-channels


【解决方案1】:

假设 Usermie 是您的用户模型。这意味着您在 settings.py 中有 AUTH_USER_MODEL='yourapp.Usermie'

如果你不使用to_field,你可以这样做,

我认为您需要执行以下操作

Postmie.objects.create(feed=feed, body=post email=request.user)

或者你可以这样做

Postmie.objects.create(feed=feed, body=post email_id=request.user.id)

您应该知道,每个外键通常在数据库中表示为带有附加 _id 的字段名称。这就是 Django 放置外键的方式。通常你应该直接使用Django的ORM。

如果你使用 to_field:仅在 Django > 1.10

根据documentation,电子邮件应该是唯一的。

如果在创建 Postmie 后更改了 to_field。请确保该列中的所有值都有新的对应值。

【讨论】:

  • 这不起作用。我认为这是因为request.user.id 没有带回字符串,或者它没有给出可存储的值或可以在此“上下文”中在数据库中表示的值。一个合适的“上下文”就像在我有request.user.username 的导航栏中一样,它在 html 页面中将用户名作为字符串提供给您,但在 Django 的函数中,它被解释为其他内容。这就是我至少从中得到的。感谢您的帮助!
  • 想想看,request.user.idrequest.user.something 在所有上下文中都应该是一个字符串。
  • 我认为您在 settings.py 中缺少 AUTH_USER_MODEL = 'yourapp.Usermie'。这应该使用您的模型作为 AUTH_USER 并将其附加到 request.user。在所有情况下 id 或 pk 总是整数。如果您在 Usermie 模型中有一个与 User 的一对一字段。您可以使用 request.user.usermie 作为反向关系。
  • 我的AUTH_USER_MODEL = 'usermie.Usermie' 中实际上有我的settings.py,并且所有内容都已注册admin.py。我可以在 html 页面 {{ request.user.email}} 上执行此操作,并将其呈现为 html 页面上的字符串。但由于某种原因,将其放入数据库中不起作用。
  • 为什么使用 to_field?如果您改用“email=request.user.email”,您能检查一下吗? docs.djangoproject.com/en/1.10/ref/models/fields/…
猜你喜欢
  • 2017-05-13
  • 2013-02-28
  • 2017-03-06
  • 2016-11-22
  • 2020-03-07
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
  • 2017-09-04
相关资源
最近更新 更多