2017-01-01 5 views
0

Я использую каналы Django, и я хочу, чтобы иметь возможность сохранять дополнительные поля в базе данных вместе с данными json сообщения.Сохраните дополнительные данные в базе данных Django

У меня есть внешний ключ в моей модели Postmie, которая указывает на email поле в моей модели пользователя. Postmie - это модель, отвечающая за сохранение сообщений в базе данных. Внешний ключ создает поле под названием email_id. Хотя я сохраняю сообщения в базе данных, я хочу также захватить электронную почту пользователя, создавшего сообщение, и сохранить его в базе данных. Как я могу это сделать? Я не использую Django-формы.

Моя Postmie модель такая же, как тот, в Django Channels учебник Post нашел here, единственное отличие состоит в том, что моя модель имеет дополнительный внешний ключ, ссылающийся на поле электронной почты в моей модели пользователя.

email=request.user.email не работает. Я думал о том, чтобы поместить электронную почту в скрытое поле, но мне это не кажется безопасным.

Метод, который я использую, практически тот же метод в учебнике Django Channels, который найден hereconsumers.py. Все работает, но я не могу вводить другие поля в базе данных для сообщений.

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 
+0

Что вы подразумеваете под «Внешним ключом создается поле, называемое email_id». Можете ли вы показать нам модель Postmie? Можете ли вы использовать пользователя в качестве ключа foriegn? –

+0

Я добавил модель 'Postmie'. Внешний ключ, который я создал, называется 'email'. Но столбец, созданный в базе данных, называется 'email_id'. То же самое с полем 'feed', имя столбца в базе данных называется' field_id'. Я думаю, что это способ Django делать вещи. – Jam1

+0

Здесь проблема 'email_id' - это' id' объекта электронной почты foreignkey.Вы можете создать сигнал 'post_save', который будет создавать объект электронной почты, и связать с ним этот объект. – karthikr

ответ

0

Предполагая, что Usermie ваша модель пользователя. Это означает, что у вас есть AUTH_USER_MODEL = «yourapp.Usermie» в settings.py

Если вы не используете 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 поместил внешний ключ. Обычно вы должны использовать ORM Django напрямую.

Если вы используете to_field: Только в Джанго> 1,10

Согласно documentation, адрес электронной почты должен быть уникальным.

Если to_field изменяется после создания Postmie. Убедитесь, что все значения в столбце имеют новое соответствующее значение.

+0

Это не сработает. Я думаю, что это потому, что 'request.user.id' не возвращает строку или это то, что не дает значения, которое может быть сохранено или может быть представлено в базе данных в этом« контексте ». Подходящий «контекст» будет похож на мой навигатор, где у меня есть «request.user.username», и он дает вам имя пользователя в виде строки на странице html, но в функциях Django это интерпретируется как нечто другое. Это то, что я получаю от него, по крайней мере. Спасибо за помощь! – Jam1

+0

Подумайте об этом: 'request.user.id' или' request.user.something' должен быть строкой во всех контекстах. – Jam1

+0

Я думаю, что вам не хватает AUTH_USER_MODEL = 'yourapp.Usermie' в ваших settings.py. Это должно использовать вашу модель как AUTH_USER и прикрепить ее к request.user. Во всех случаях id или pk всегда являются целыми числами. Если у вас в модели Usermie есть поле «один к одному» для пользователя. Вы можете запросить user.user.usermie как обратное отношение. –