Update path to static
@@ -18,4 +18,4 @@
|
|||||||
|
|
||||||
#### Screenshot
|
#### Screenshot
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<link rel="shortcut icon" href="/img/favicon.ico" />
|
<link rel="shortcut icon" href="/static/img/favicon.ico" />
|
||||||
<title>{% if page.title %}{{ page.title }} - {{ site.title }}{% else %}{{ site.author }}{% endif %}</title>
|
<title>{% if page.title %}{{ page.title }} - {{ site.title }}{% else %}{{ site.author }}{% endif %}</title>
|
||||||
<meta name="author" content="{{ site.author }}" />
|
<meta name="author" content="{{ site.author }}" />
|
||||||
<meta name="description" content="{% if page.title %}{{ page.title }}{% else %}{{ site.description }}{% endif %}" />
|
<meta name="description" content="{% if page.title %}{{ page.title }}{% else %}{{ site.description }}{% endif %}" />
|
||||||
@@ -13,23 +13,23 @@
|
|||||||
<link rel="alternate" type="application/rss+xml" title="RSS" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="RSS" href="/feed.xml">
|
||||||
|
|
||||||
<!-- syntax highlighting CSS -->
|
<!-- syntax highlighting CSS -->
|
||||||
<link rel="stylesheet" href="/css/syntax.css">
|
<link rel="stylesheet" href="/static/css/syntax.css">
|
||||||
|
|
||||||
<!-- Bootstrap core CSS -->
|
<!-- Bootstrap core CSS -->
|
||||||
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Fonts -->
|
<!-- Fonts -->
|
||||||
<link href="//fonts.googleapis.com/css?family=Roboto+Condensed:400,300italic,300,400italic,700&subset=latin,latin-ext" rel="stylesheet" type="text/css">
|
<link href="//fonts.googleapis.com/css?family=Roboto+Condensed:400,300italic,300,400italic,700&subset=latin,latin-ext" rel="stylesheet" type="text/css">
|
||||||
|
|
||||||
<!-- Custom CSS -->
|
<!-- Custom CSS -->
|
||||||
<link rel="stylesheet" href="/css/super-search.css">
|
<link rel="stylesheet" href="/static/css/super-search.css">
|
||||||
<link rel="stylesheet" href="/css/main.css">
|
<link rel="stylesheet" href="/static/css/main.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<a href="/"><img id="about" src="/img/avatar.jpg" height="75px" width="75px" /></a>
|
<a href="/"><img id="about" src="/static/img/avatar.jpg" height="75px" width="75px" /></a>
|
||||||
<h1 class="author-name">{{ site.author }}</h1>
|
<h1 class="author-name">{{ site.author }}</h1>
|
||||||
{% if site.about %}
|
{% if site.about %}
|
||||||
<div id="about">
|
<div id="about">
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
================================================== -->
|
================================================== -->
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
|
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
|
||||||
<script src="/js/bootstrap.min.js"></script>
|
<script src="/static/js/bootstrap.min.js"></script>
|
||||||
<script src="/js/super-search.js"></script>
|
<script src="/static/js/super-search.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: "Adding BroadCast Mail to All Users Registered inside Django Admin"
|
||||||
|
date: 2016-04-19 19:51:02 +0700
|
||||||
|
categories: [python, django]
|
||||||
|
---
|
||||||
|
|
||||||
|
Adding BroadCast Mail to All User Registered in Django Admin. This is my last problem, we need custom default Django Admin to can submit BroadCast mail to All User. Because this is perfectly to make a promotions.
|
||||||
|
|
||||||
|
This problem has been helped by our Danny W. Adair who are answered someone's question about the ["Django Admin Customizing"](http://stackoverflow.com/a/5803941/3445802 target="_blank").
|
||||||
|
|
||||||
|
> In this configuration, we use gmail for email backend. Please following this tutorial first [Email BackEnd with SMTP Gmail](https://agusmakmun.github.io/python/django/2016/04/18/email-backend-with-smtp-gmail.html).
|
||||||
|
|
||||||
|
**1.** In your `models.py`
|
||||||
|
|
||||||
|
{% highlight python %}
|
||||||
|
class BroadCast_Email(models.Model):
|
||||||
|
subject = models.CharField(max_length=200)
|
||||||
|
created = models.DateTimeField(default=timezone.now)
|
||||||
|
message = RichTextUploadingField()
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.subject
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = "BroadCast Email to all Member"
|
||||||
|
verbose_name_plural = "BroadCast Email"
|
||||||
|
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
**2.** In your `admin.py`, importing some module for "admin" and for "email setup".
|
||||||
|
|
||||||
|
{% highlight python %}
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
import threading
|
||||||
|
from django.conf import settings
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.core.mail import (send_mail, BadHeaderError, EmailMessage)
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
class EmailThread(threading.Thread):
|
||||||
|
def __init__(self, subject, html_content, recipient_list):
|
||||||
|
self.subject = subject
|
||||||
|
self.recipient_list = recipient_list
|
||||||
|
self.html_content = html_content
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
msg = EmailMessage(self.subject, self.html_content, settings.EMAIL_HOST_USER, self.recipient_list)
|
||||||
|
msg.content_subtype = "html"
|
||||||
|
try:
|
||||||
|
msg.send()
|
||||||
|
except BadHeaderError:
|
||||||
|
return HttpResponse('Invalid header found.')
|
||||||
|
|
||||||
|
class BroadCast_Email_Admin(admin.ModelAdmin):
|
||||||
|
model = models.BroadCast_Email
|
||||||
|
|
||||||
|
def submit_email(self, request, obj): #`obj` is queryset, so there we only use first selection, exacly obj[0]
|
||||||
|
list_email_user = [ p.email for p in User.objects.all() ] #: if p.email != settings.EMAIL_HOST_USER #this for exception
|
||||||
|
obj_selected = obj[0]
|
||||||
|
EmailThread(obj_selected.subject, mark_safe(obj_selected.message), list_email_user).start()
|
||||||
|
submit_email.short_description = 'Submit BroadCast (1 Select Only)'
|
||||||
|
submit_email.allow_tags = True
|
||||||
|
|
||||||
|
actions = [ 'submit_email' ]
|
||||||
|
|
||||||
|
list_display = ("subject", "created")
|
||||||
|
search_fields = ['subject',]
|
||||||
|
|
||||||
|
admin.site.register(models.BroadCast_Email, BroadCast_Email_Admin)
|
||||||
|
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
**3.** And then, you can see. we have **Submit BroadCast** selection, just click button **Go** to submit broadcast mail.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
BIN
static/img/_posts/Broadcast_Mail.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |