Integrating Django and WordPress can be simple.

This video features Collin Anderson at DjangoCon US 2014 in Portland, Oregon, USA.

Integrating Django and WordPress can be simple.
0:27:37
Published September 16, 2014
7,760 views

By, Collin Anderson
I found it surprisingly easy to do a simple integration of Django with an existing WordPress blog. I use Django to display content from WordPress’s database. I’ll explain how I integrated them and what made things easy.

Help us caption & translate this video!

http://amara.org/v/FOPW/

Summary

Collin Anderson argues that Django can serve the public-facing side of a WordPress site while WordPress remains the content-management interface. This avoids rebuilding mature editorial features such as the WYSIWYG editor, media library, autosave, revisions, metadata, and comment moderation, while letting developers use Django templates, models, feeds, caching, and Nginx for the site itself. He describes sharing WordPress’s MySQL database with Django, using `inspectdb` and a small amount of model cleanup, and recommends keeping the integration simple: avoid plugins and custom PHP, use PHP-FPM behind Nginx, and add Django support for WordPress features only when needed.

Key takeaways

  • WordPress provides a mature editorial workflow with rich text editing, media management, autosave, revisions, metadata, and comment moderation.
  • Django can read and serve WordPress content directly by mapping its existing database with `inspectdb`, then adding foreign keys and relationships.
  • Keeping WordPress limited to content editing and avoiding plugins or custom PHP reduces maintenance and security problems.
  • Running PHP-FPM and Django behind Nginx allows the two systems to coexist, with Nginx also supporting effective caching.
  • The approach preserves the option of replacing WordPress with a Django admin later, once the rest of the site is established.

Summarised automatically from the transcript.

Chapters

  1. 0:00 Background and Case Study Collin Anderson introduces his Django experience and the client project that motivated combining WordPress with Django.
  2. 1:54 WordPress and Django Challenges The talk examines security, plugins, PHP, templates, and multi-database problems in a mixed WordPress and Django setup.
  3. 4:13 Blog Migration Options The speaker compares building a Django blog from scratch with adopting an existing Django blog application.
  4. 8:51 Hybrid WordPress Administration WordPress remains the content-editing interface while Django serves the public-facing website.
  5. 12:00 PHP-FPM and Nginx Setup The talk covers a minimal deployment configuration for running WordPress through PHP-FPM and Nginx.
  6. 15:03 Shared Database Architecture The speaker explains consolidating WordPress and Django into one database and using Django to access WordPress content.
  7. 15:48 Django Models and Content Serving The implementation uses database introspection, relationships, queries, feeds, shortcodes, and forms to serve WordPress content through Django.
  8. 18:14 Trade-offs and Future Migration The speaker discusses limitations, reliability, and the possibility of replacing WordPress administration with Django later.
  9. 19:07 Web Content and Applications A broader distinction is drawn between cacheable, mostly read-only web content and interactive web applications.
  10. 21:41 Questions The speaker answers questions about caching, WordPress multisite, authentication, custom WordPress installations, and Nginx.

Transcript

4,316 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:20

Uh

0:21

Speaker 1: WordPress. I'm actually gonna have a lot of slides with code and I'm gonna go through them quickly. So I recommend pulling up the slides if you want to look at them later or look more at an individual slide. But here we go. There's me. Um I uh I started using PHP in 2002 and then in 2006 I found Django. And this is actually the Wayback Machine for the Django website. You probably couldn't tell besides the latest release being. 95. over from 110 communications and we make client websites. We have about 20 live Django client websites for clients.

1:08

Speaker 1: Many of them started a while ago before 1. 0 All of them are at least Django 1. 6, I say at least because I made sure to upgrade a few of them to 1. 7 uh now that it's out. Um and actually a lot of them can run against master without warnings, which I'm pretty proud of. So we had a situation we had uh a five-year-old WordPress site with a modified theme we built back in the day. Wasn't that fun to modify the theme and it's wasn't that fun to support. It's WordPress. Wasn't quite that fun. WordPress is built in PHP. And then we also had a Django website for them that handled like an internal directory. And

1:54

Speaker 1: there are problems mixing WordPress and Django. A lot of the problems are with WordPress. Old versions of WordPress frequently get hacked and you'll get like spam on your site and advertising. And if you leave your WordPress site around, it will probably eventually get hacked because it's a very popular product and people find vulnerabilities and then write a bot that'll search. websites for that and then it'll you'll get hacked automatically and won't even be targeted. Plugins are not fun. No one likes buggy plugins. WordPress has lots of plugins and Uh it's not fun to debug things in PHP.

2:39

Speaker 1: There's no pretty Django tracebacks. Um PHP is in itself is a problem. The quote is I don't know how to stop it. There was never any intent to write a programming language. I've absolutely no idea how to write a program language. I just kept adding logical step along the way, says a creator of PHP. So once you try Python, you just don't ever want to go back to PHP. Templates are interesting. It's no fun to mix PHP templates and Django templates, uh although someone found a way to run arbitrary PHP code in Django templates. Why would you do that? I don't know, but someone wrote a package for that. Multiple databases are also not fun

3:26

Speaker 1: having to Um multiple databases, one for Django, one for WordPress. It's not that much fun. It's twice the work pretty much everywhere This next slide isn't really working, but that's okay. I'm worried about mixing PHP and Python and P in uh Apache. I talked to Graham Dumbleton about this. Um and he says it actually is not as bad as you would think and he actually wrote up a whole blog post yesterday, right before his talk, explaining how to do it and uh it's kind of funny. Like while I was talking to him, he like Wrote 10 lines of code in Mod Whiskey that actually makes it a lot easier to use PHP with mod whiskey, as funny as that sounds.

4:13

Speaker 1: So my solution is let's use Django for everything. This is what the website looks like now, and convert the blog to Django. At least so I started looking, okay, what what Django blog application should we use? We got a lot of options. Which one do you pick? Or do you even use one? You can also just make your own blog model. You have full control and it's actually kind of fun. A lot of people do this. It's a good like starter project if you're uh interested in learning more about Django, run your own blog for a while. You'll learn a lot and it's like a real something really you can do to learn Django. But when you do it, you've got to decide, okay, well what fields do I want?

4:58

Speaker 1: Do I want a title field, a slug field, how do authors work, you know? What what sort of fields do I need in my blog model? There's an unlimited number of options. How do you decide? Sometimes it's even harder when you're working with a client. Like, okay, well, what do you want on your blog model? It can take some work to figure out, but it's possible. And how much work is it going to take to migrate existing content? uh into into your blog model. This is some code I wrote four years ago to migrate a bunch of um data into a blog model that I made. Actually yeah we forked it from one of the other ones.

5:44

Speaker 1: And how do you edit content? So initially, if you just make a blog model in the admin, you're going to get a field that looks like this. It's just raw raw HTML. Is that what you're going to give to your client if if you're doing client websites like we are? Are you going to install and configure Tiny MCE for WYSIWYG editor, you know, figure out all the configuration and then install it? uh work out all the bugs, or do you use CK editor? Um as far as I can tell, their documentation is really bad, but it's what Drupal uses. And or do you just teach them markdown? So markdown, a lot of us like markdown, but are you gonna teach the client how to use markdown, hold their hand through stuff, um tell them how to you know

6:29

Speaker 1: make links and such? Or do you teach them rest? You know, here's another way. Um gotta decide all that. Anyway, it could take uh It could take days to figure out, make those decisions. Um how are you going to work with images and videos? So uploading an image, get it right in the blog post, do you resize it? Do you you know you want to allow embedding YouTube videos and such? There's a lot that can go into it. Django, this is Django prod uh Django Packages. com and that has a bunch of competing options. So you could pick you could pick one of these, install it, and configure it and make sure it works together. And then there's just like, you know, whenever you're building something, you could just build

7:17

Speaker 1: keep on building features. Do you want to do like a read more split where you have a bunch of text on your home page and then there's like a read more and you click it and then there's the rest? And do you want to make make a way in the admin to specify where that split is? Are you going to do comment moderation? Are you going to use discuss? Are you going to use Are you going to do comments in Django? Are you going to do autosave? I've had someone use one of the uh the Django admin before and they're like, so do you autosave it all? Because I just wrote a bunch and I think I lost it all. Um there's also are you gonna do revisions so that if you don't accidentally if you do accidentally delete something out you can go back and get previous versions of stuff?

8:06

Speaker 1: Are you gonna do a thumbnail for each post? Um like On the homepage, you know, you want like the image for the post, but your post actually has a bunch of images in the content field. How do you pick the right one and how do you make it look right? And then you can have like a media browser. I think there's a bunch of Django plugins that can also do that. But you gotta kinda install it and make it work with your WYSIWYG editor. And you may want like a pop-up where you can browse. all of the possible images and it can just kind of go on. So you could do all that using Django. But how long is it going to take? And are there going to be bugs? You know, we do client work, so you've got to estimate out how much it's going to take. But I

8:51

Speaker 1: think there's a way to keep it simple. What if we u what if we keep the WordPress in the admin? So we're migrating from an existing WordPress website. What if we keep WordPress for editing content? And then use Django for actually serving that content out. And Django is actually the public-facing side of the website. The admin is just for whoever's actually editing content. What if we keep that as the admin for editing stuff in the database and Use Django to actually serve that content. Apparently WordPress actually has a kind of decent editing experience. has a WYSIWEG editor that's already been picked, installed, has autosave revisions, it has a media library, it has a custom key value metadata.

9:41

Speaker 1: This is kind of cool where it's like I just need another field. It's not handled in there. WordPress just kind of has this thing built in out of the box where you can add name and value pairs. It can be really handy. Uh it has built-in comment moderation, uh and it's it's getting more and more mobile friendly. Um And it, you know, it looks pretty good. It has good CSS. Um so it all just works together out of the box. Uh there are not that many bugs and They spent years improving the user interface and probably will continue to uh I kind of like this connection lost feature where it's like backing up in the browser just in case you lose a connection.

10:27

Speaker 1: The post model has aged well in 13 years, so they've they came up with something, you know, found all sorts of problems with it and keep revising and revising and revising and tweaking it. I don't need to think about what fields I need if I can just use that. It's pretty mature and it works. I know it works because at least three people use it. So it in general uh it's kind of a time saver. So I I don't need to worry about bugs in the admin. Tiny MCE has already been uh installed, fully configured, I know it works. Um the fields have already been decided. Um I'm sure a lot of you want to do customization and get it, have full control and get it exactly how you want, but

11:15

Speaker 1: sometimes you just you actually don't care and you care more about the front end and how it looks. It's also really easy to migrate from WordPress. You just start using the database. And you don't have to write a bunch of database migration code because the models are exactly the same. And it means I have more time for the front end and other sections of the website. So you can get something up and running fast and It works and uh I can work on I think we also we also did another section of the website that we actually did use Django, use the admin and everything, and I had a lot more time to work on that section of the website because I didn't need to worry about all the the individual WYSIWYG issues in the admin for the blog.

12:00

Speaker 1: It was just kind of fully featured out of the box. And you're probably saying, but it's PHP, yuck! Didn't we just go through all bad PHPs? Um but I think you can do it if you keep it simple. Follow these rules. So you can keep WordPress running using this thing called PHPF. FPM, FastCGI Process Manager , which is really simple. You just hook it directly up to Nginx. You just install On Ubuntu or Debian you just say sudo app to get install, PHP FPM, and then you also got install MySQL. And I'll read through quickly the Nginx. This is pretty standard. You got your server name. And then the client max body size 4 gigabytes, that means allow

12:46

Speaker 1: basically allow uploads to the website, don't block them. You get these Weird errors if you don't. Uh stick all your PHP files in slash path slash two slash php. I don't know if anyone actually goes through examples and then creates like a path folder in the root of their of their uh file system, you know, that's actually just a placeholder. You can put that wherever you want, but I'm sure some people actually create path. Anyway. Uh try files means like uh first check to see if there's a static file matching the URL. If not, pass it to index. php. Um this allows pretty URLs. And then Finally, if you do hit a PHP file, pass it over to FastCGI. FastCGI by default

13:32

Speaker 1: listens on this socket, at least In the latest version of Ubuntu. It just listens on a Unix socket, Unix socket, and works. You can can uh configure FPM if you want, but it just works out of the box as it is. for starters. And if you're not using Nginx, why not? It's it's really good. I highly recommend it. This is a scary feature. WordPress updates itself. So the security issues that I used to run into, WordPress will now actually automatically install security updates when they come out. And they'll even have like a button, there's a reinstall now button, there's a

14:17

Speaker 1: you can also hit the button to upgrade to the next major version. Totally scary, but apparently it works. I have doubts, but I think apparently it works. But so once you have that, just don't touch WordPress. Don't install any plugins. It'll open you up to problems, you know. If you do have to, you may need to, but like you gotta fight and try not to do plugins. Also don't write any custom PHP. You'll need to maintain it. This is the PHP hammer. So don't run any custom PHP code because you have to maintain it and debug it and it's not fun. You have to do you have to configure um WordPress, that's wpconfig. php, but besides that

15:03

Speaker 1: I recommend not doing any PHP code. Turns out you can just consolidate WordPress's database with Django's database. So I I use MySQL, of course you can all use Postgres, but If you want to do WordPress, you've got to use MySQL. So I'm just dumping the WordPress database into the Django database. The WordPress database uses these WP underscore prefixes, so you're not going to get any table clashes, and it's actually a lot easier to maintain a backup just one database because it's one website now. There's a project called Django WordPress that you can add to your installed apps and your URLs, and it'll actually just start handling your blog and It understands the WordPress database and it'll serve up your content.

15:48

Speaker 1: It has date-based archives and such, and you just write the templates. I looked into that and actually I decided, you know, there's actually, I bet I could just do this from scratch. And you get a little bit more control and it's actually kind of fun. And it's really not that much work. I assume half of you just went to the Talk on inspectDB and inheriting a database. That's basically what we're gonna do. Basically what I did was dumped uh ran spec db dumped it into models. py and got something kind of like this um which works um Although I did have to set up foreign keys, that was probably the biggest thing.

16:35

Speaker 1: I also figured out there's a pretty simple, you can set up a simple many-to-many for categories and tags. And that worked for me. And just set up all the foreign keys, link all the models together, because InspecDBE doesn't handle that quite right out of the box. Once you have that, queries are really simple. You just filter by. um posts as opposed to like revisions of posts or um images or uh pages. Uh so I want posts and I want the ones that are published. Now I have post objects. Django just knows it out of the box. Django has RSS and Atom feeds out of the box, and it's really simple. One thing I ran into is WordPress sticks in these crazy short codes for like saying, yes, I want an image here and there's some information about it.

17:27

Speaker 1: And I wrote some really hacky, messy code to get that. I bet there's ways to improve it, but this is just regular expressions and splits. It's totally ugly. Don't use it. But it's it's possible. Comments are really simple. I just use a model form and say I want the author, the email address, and the actual content of the comment. You can also add in the author URL. WordPress has handy fields for collecting the IP address and user agents, so hey, why not? And then it's just a basic model. basic model form saving and creating um and then redirecting.

18:14

Speaker 1: Uh so disadvantages. It's PHP, right? We all use Python because it's simply better. I can't support every possible feature of WordPress on the Django side, but I can support them as I need them. There's like widgets, um they're available in WordPress admin. I don't actually have the front end um For that, but I can support them later if needed. And the database can change over time, though it's actually been pretty stable recently. Um I think it's been like two years since they made a database change. And it's it's simple. So I can get the website up and running very, very, very quickly. Um and actually I can even shut off the WordPress. website and the Django website is still there. So WordPress just edits the content, Django serves the content, even though it's read-only, the website's still there, and if WordPress goes down, that's totally fine.

19:07

Speaker 1: And I'm always free to ditch WordPress and use the Django admin later. So, you know, I got I got stuff up and running now. Um we find actually we're quite limited by what's going on here. I can always start using real Django for the admin also. Good, and here's a uh so that's Most of what I have to say, uh lunch is happening soon, but why not a cat photo and then a couple totally random anecdotes on web versus application. This is just totally off topic, but it's something I've been thinking about. um a distinction between what's the difference between a web application and web content. So content web pages should work without JavaScript.

19:53

Speaker 1: They're served by GET. They generally don't change per person, and the content usually shows up in Google search results. Google indexes content. And generally they read only the user. You like you find something on the internet and you read it. And generally things are easy to build and easy to cache because they don't change much. Uh web applications on the other hand are usually behind login, they're usually invisible to search engines, and they make use of like post and other HTTP verbs. So like you know, like a REST API. There's plenty of talks on the REST API. That's that means you're building a web application. Um and it's usually okay to acquire JavaScript and actually you're usually JavaScript heavy and using Angular. js and such.

20:38

Speaker 1: And it's user-specific, the users editing things and changing things and working with your website. And it's actually a lot harder to get right than content. It's actually uh in my opinion, it's a lot more work to allow the user to edit things versus just the user reading things. So in my case, WordPress is the application and Django serves the content. End of anecdotes, I have 15 seconds for a really crazy idea. What if we rewrite the WordPress admin in PHP from PHP and use Django for it? So like keep the keep the JavaScript and the CSS in sync with WordPress and then we build like this compatibility where you build a compatible backend that uses the WordPress API and enjoy life PHP free.

21:26

Speaker 1: Uh it would be a lot of work. Crazy idea. I don't expect you to understand it, but I think it's cool. And that's all I got. Thanks.

21:41

Speaker 2: Any questions for Colin? I think they're just digesting out.

21:46

Speaker 1: Yeah, yeah. I went really fast.

21:48

Speaker 2: Oh.

21:50

Speaker 3: Um so I have a client who has a WordPress site and has hopped from host to host just for performance reasons. You know, find someone who caches. differently or something. I suspect using Django and Nginx that becomes a non-issue. Is that your experience?

22:08

Speaker 1: Um as far as caching goes. Just

22:10

Speaker 3: per I mean sir the speed of serving all the content.

22:13

Speaker 1: Yeah, yeah. I mean if you're direct if you were serving Apache directly and being at some host that uses Apache, um Nginx's gonna be way faster, assuming it's serving static files properly. Um It's also really easy to set up um uh I I really like WordPress has uh sorry, NGMX has proxy underscore cache. Which is a directive and you can basically do a full page caching on whatever is coming back from Django, um, which I think is really cool. And there are there are lots of options of how to speed up the website and I imagine especially because if you if you do do it from scratch and using Django, you can have a lot more control of what are the database queries being run and such.

22:59

Speaker 3: So you have used caching doing it this way.

23:02

Speaker 1: Say that again.

23:02

Speaker 3: I said you have used caching doing it this way?

23:05

Speaker 1: Yeah, I have. Uh yep. Yeah.

23:10

Speaker 4: I was just wondering if you'd ever looked into like combining the the WordPress multi-site stuff with Django or where that

23:18

Speaker 1: Yeah, I have. I don't know. I've I've looked into WordPress uh multi site and you know it's like is this something also worth doing and As far as I can tell, WordPress multi-site is kind of just a big hack. And even in the WordPress community, it's like it kind of works and kind of doesn't. Um one actually real issue is um WordPress multi-site will put like a table prefix on everything. Um so each site will have the same will have separate database tables just with a different prefix. And I think that would require some That really confuses Django. So I just try to avoid it

24:06

Speaker 1: and rather just do a separate database if I'm doing multiple.

24:14

Speaker 5: So Django has the great uh authentication backend abstraction. And uh um I was just wondering if um so you could probably theoretically use Django to authenticate against WordPress. Is do you know of any ways you can get WordPress to authenticate against Django? Um or

24:30

Speaker 1: Right. Um Yeah, so that's one thing too, is like I'm just kind of assuming that the person's gonna need to log into two places, have two different usernames and passwords. That's one of the downsides. Um uh I'd recommend uh I I think I once We once had a case where we like installed an LDAP backend to try to get WordPress and Django to share usernames and passwords. It what really wasn't fun. It's a lot of work. I I'd rather go the route of having Django use the WordPress user model as a custom user model. I haven't actually tried it, but I bet it's theoretically possible. And then you're actually using the same username and password and reusing it. Uh

25:13

Speaker 5: thank you. Um

25:16

Speaker 3: that's awesome. Um I uh I know everyone hates PHP and everyone hates WordPress, no one more than me, but the place that I work

25:24

Speaker 6: um runs uh almost 200 different WordPress sites, busy WordPress sites off of a single WordPress industry install without using multi-user. And the key is no plugins. They write everything themselves. So if you need the functionality of a plugin, they just write it themselves. themselves super secure and it's really stable and really fast. And when when an update comes out, they can run it and they know that it'll work because there's no they know where every um

25:54

Speaker 1: They know every line of code.

25:59

Speaker 6: It's super secure. And I'm the guy that's always trying to I'm writing the Django stuff and I'm always messing around with the database. So I'm gonna I need your uh Card is but above you.

26:17

Speaker 4: So the the the last I knew is WordPress seemed to really favor Apache because it comes with the HT access that you need to run. Was it easy to just convert over to Nginx?

26:28

Speaker 1: Yeah, and like WordPress is also just like we're discovering Nginx, WordPress is also discovering Nginx and uh they they have documentation of how like the perfect way to set up Nginx is. Um I just used I kind of copied just like the bare minimum of what you would need to set up WordPress with Nginx. And there's a couple more things you can do to tweak this and make it better. Um generally WordPress is like supports Nginx more and more.

27:05

Speaker 2: It's gonna talk us out of the Postgres to go back to MySQL. But thank you. I think it's lunchtime, everyone. Thank you so much, Colin.

Questions this talk answers

How can I use Django for a WordPress site without replacing WordPress entirely?

Keep WordPress as the content-editing backend and let Django serve the public-facing site. Django reads the WordPress content while WordPress provides the mature editor, media library, revisions, autosave, and moderation tools.

Discussed at 8:51

Why keep WordPress as the admin instead of building a Django blog admin?

WordPress already provides a polished, fully configured editing experience, so you avoid implementing fields, rich-text editing, media handling, revisions, autosave, and other features yourself. This saves development time and leaves more time for the front end and other Django sections.

Discussed at 8:51

How do I run WordPress with Nginx and Django?

Run WordPress through PHP-FPM and connect it directly to Nginx, while Django handles the public routes. Nginx serves static files, passes WordPress requests to PHP-FPM, and can route the Django portion separately.

Discussed at 12:00

Can Django and WordPress use the same database?

Yes. The speaker places WordPress’s MySQL tables in the Django database; WordPress’s `wp_` table prefixes prevent collisions, and using one database simplifies backups and maintenance.

Discussed at 15:03

How can Django read and serve WordPress content?

You can use the Django WordPress package or reverse-engineer the existing schema with `inspectdb`, then connect the generated models with the necessary foreign keys and many-to-many relationships. Django can then query published posts, render templates, and provide feeds such as RSS and Atom.

Discussed at 15:48

Does using Django with WordPress improve site performance and caching?

Using Nginx to serve static files can be faster than serving them directly through Apache, and Nginx’s proxy cache can provide full-page caching for Django responses. Django also gives you more control over the database queries when you implement the frontend yourself.

Discussed at 22:13

Can WordPress multisite be combined with Django?

The speaker recommends avoiding WordPress multisite because its prefixed, separate table sets are confusing for Django. For multiple sites, he would rather use separate databases.

Discussed at 23:18

How can WordPress and Django share user authentication?

The straightforward setup requires users to log in separately, though the speaker suggests that Django could theoretically use the WordPress user table as a custom user model. He had not tried that approach, and an LDAP-based shared-login setup had proved unpleasant to implement.

Discussed at 24:30

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from DjangoCon US