Save additional data to Django database

550 views Asked by At

I am using Django Channels and I want to be able to save additional fields to the database along with the json data of the post.

I have a foreign key in my Postmie model that points to email field in my user model. Postmie is the model responsible for saving posts to the database. The Foreign key creates a field called email_id. While I am saving posts to the database I want to also grab the email of the user making the post and save it in the database as well. How can I go about doing this? I am not using Django forms.

My Postmie model is the same as the one in the Django Channels tutorial Post found here, the only difference is that my model has an extra foreign key pointing to the email field in my user model.

email=request.user.email does not work. I was thinking about putting the email in a hidden field, but that does not seem safe to me.

The method I am using is practically the same method in the Django Channels tutorial found here consumers.py. Everything works but I am not able to enter other fields in the database for posts.

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 model:

@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
1

There are 1 answers

8
Ahmed Hosny On

Assuming that Usermie is your user model. This means that you have AUTH_USER_MODEL='yourapp.Usermie' in settings.py

If you are not using to_field, You can do,

I think you need to do the following

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

Or you can do

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

You should know that every foreign key is usually represented on the database with the name of the field appended with _id. This is how Django put the foreign key. Usually you should use the ORM of Django directly.

If you are using to_field:Only in Django > 1.10

According to the documentation, email should be unique.

If to_field is changed after Postmie is created. Please make sure that all values in the column have the new corresponding value.