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
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
Or you can do
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.