LEMP 기반으로 우분투에 설치된 워드프레스를 Django 프레임워크와 연동하여 관리해보자. 본 예제에 앞서 진행되어야 할 관련 포스팅은 아래 내용을 참고한다.
- 우분투 18.04에 워드프레스 설치하기 How To Install WordPress with LEMP on Ubuntu 18.04 https://antilibrary.org/1884
- 우분투 18.04 에 Nginx phpMyAdmin 설치하기 Installing phpMyAdmin for Nginx on Ubuntu 18.04 https://antilibrary.org/1901
장고 설치 및 워드프레스 DB 연결
먼저 장고를 설치한다. 금일 기준 최신 버전은 Django 2.1.3 이다.
1 2 3 4 5 6 7 8 9 10 | (dominika) founder@hilbert:~$ pip install Django==2.1.3 Collecting Django==2.1.3 Downloading https://files.pythonhosted.org/packages/d1/e5/2676be45ea49cfd09a663f289376b3888accd57ff06c953297bfdee1fb08/Django-2.1.3-py3-none-any.whl (7.3MB) 100% |████████████████████████████████| 7.3MB 2.4MB/s Collecting pytz (from Django==2.1.3) Downloading https://files.pythonhosted.org/packages/f8/0e/2365ddc010afb3d79147f1dd544e5ee24bf4ece58ab99b16fbb465ce6dc0/pytz-2018.7-py2.py3-none-any.whl (506kB) 100% |████████████████████████████████| 512kB 21.0MB/s Installing collected packages: pytz, Django Successfully installed Django-2.1.3 pytz-2018.7 | cs |
장고가 제대로 설치되었는지 확인하고 새로운 프로젝트를 생성하자.
1 2 3 4 5 6 7 8 9 10 11 | (dominika) founder@hilbert:~$ python -m django --version 2.1.3 (dominika) founder@hilbert:~$ mkdir teamgalois (dominika) founder@hilbert:~$ cd teamgalois (dominika) founder@hilbert:~/teamgalois$ django-admin startproject teamgalois (dominika) founder@hilbert:~/teamgalois$ ls -al total 12 drwxrwxr-x 3 founder founder 4096 Nov 10 08:29 . drwxr-xr-x 15 founder founder 4096 Nov 10 08:29 .. drwxrwxr-x 3 founder founder 4096 Nov 10 08:29 teamgalois | cs |
호스트를 추가하고, 8000 포트로 장고 서비스를 실행한다.
/home/founder/teamgalois/teamgalois/settings.py
1 2 3 4 | ALLOWED_HOSTS = ['www.teamgalois.com'] | cs |
1 2 3 4 5 6 7 8 9 10 11 | (dominika) founder@hilbert:~$ django-admin startproject teamgalois (dominika) founder@hilbert:~$ cd teamgalois (dominika) founder@hilbert:~/teamgalois$ python manage.py runserver 0.0.0.0:8000 Performing system checks... System check identified no issues (0 silenced). November 10, 2018 - 08:53:20 Django version 2.1.3, using settings 'teamgalois.settings' Starting development server at http://0.0.0.0:8000/ Quit the server with CONTROL-C. | cs |
정상적으로 설치가 되었다.
워드프레스의 MySQL 접속 정보를 설정 파일에 입력한다.
/home/founder/teamgalois/teamgalois/settings.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | try: import pymysql pymysql.install_as_MySQLdb() except: pass DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysql', 'USER': '*******', 'PASSWORD': '************', 'HOST': 'localhost', # Or an IP Address that your DB is hosted on 'PORT': '3306', } } | cs |
아래와 같은 오류 메시지가 뜬다.
1 2 3 4 5 6 | django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module. Did you install mysqlclient? | cs |
참조링크 Error loading MySQLdb Module 'Did you install mysqlclient or MySQL-python?'
링크의 설명대로 pymysql 을 설치하고, __init__.py 파일에 아래 내용을 추가한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ~/teamgalois$ pip install pymysql Collecting pymysql Downloading https://files.pythonhosted.org/packages/a7/7d/682c4a7da195a678047c8f1c51bb7682aaedee1dca7547883c3993ca9282/PyMySQL-0.9.2-py2.py3-none-any.whl (47kB) 100% |████████████████████████████████| 51kB 1.0MB/s Collecting cryptography (from pymysql) Downloading https://files.pythonhosted.org/packages/ec/18/1583e40c38ff8572c42e56ce17b95357a9ebb91375cfbd7aad63cac9a32e/cryptography-2.4.1-cp34-abi3-manylinux1_x86_64.whl (2.1MB) 100% |████████████████████████████████| 2.1MB 10.6MB/s Collecting idna>=2.1 (from cryptography->pymysql) Downloading https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB) 100% |████████████████████████████████| 61kB 18.4MB/s Requirement already satisfied: six>=1.4.1 in /home/founder/anaconda3/envs/dominika/lib/python3.7/site-packages (from cryptography->pymysql) (1.11.0) Collecting asn1crypto>=0.21.0 (from cryptography->pymysql) Downloading https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl (101kB) 100% |████████████████████████████████| 102kB 23.0MB/s Collecting cffi!=1.11.3,>=1.7 (from cryptography->pymysql) Downloading https://files.pythonhosted.org/packages/51/7b/d1014289d0578c3522b2798b9cb87c65e5b36798bd3ae68a75fa1fe09e78/cffi-1.11.5-cp37-cp37m-manylinux1_x86_64.whl (421kB) 100% |████████████████████████████████| 430kB 4.1MB/s Collecting pycparser (from cffi!=1.11.3,>=1.7->cryptography->pymysql) Downloading https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz (158kB) 100% |████████████████████████████████| 163kB 27.4MB/s Building wheels for collected packages: pycparser Running setup.py bdist_wheel for pycparser ... done Stored in directory: /home/founder/.cache/pip/wheels/f2/9a/90/de94f8556265ddc9d9c8b271b0f63e57b26fb1d67a45564511 Successfully built pycparser Installing collected packages: idna, asn1crypto, pycparser, cffi, cryptography, pymysql Successfully installed asn1crypto-0.24.0 cffi-1.11.5 cryptography-2.4.1 idna-2.7 pycparser-2.19 pymysql-0.9.2 | cs |
/home/founder/teamgalois/teamgalois/__init__.py
1 2 3 | import pymysql pymysql.install_as_MySQLdb() | cs |
다시 장고 서비스를 실행해보자. 이번에는 접근 오류가 발생한다.
1 2 3 4 5 6 7 8 9 | packet.check_error() File "/home/founder/anaconda3/envs/dominika/lib/python3.7/site-packages/pymysql/protocol.py", line 220, in check_error err.raise_mysql_exception(self._data) File "/home/founder/anaconda3/envs/dominika/lib/python3.7/site-packages/pymysql/err.py", line 109, in raise_mysql_exception raise errorclass(errno, errval) django.db.utils.OperationalError: (1045, "Access denied for user 'jennifer'@'localhost' (using password: YES)") | cs |
위의 MySQL ERROR 1045 접근 거부는 제타 워키 설명에 나와있는대로, MySQL 패스워드가 맞지 않는 것이다. 그런데 MySQL의 경우 동일한 계정이라도, 접속지에 따라 서로 다른 패스워드를 부여할 수 있으니, 이 부분까지 체크해서 settings.py 파일을 수정한다.
일단 여기까지는 Database 셋팅의 default 값을 워드프레스 DB로 대체하여 정상적으로 접속이 되는지를 확인했다. 다음에는 db 라우팅을 통해 추가해보도록 하자.
참고로 mysql-connector-python 과 mysqlclient 어떤 점에서 차이가 나는지는 아래 링크를 참조한다.
What's the difference between MySQLdb, mysqlclient and MySQL connector/Python?
레거시 데이터베이스와 장고 통합하기
진행에 앞서 도움이 될만한 몇 가지 링크를 챙겨보자.
Integrating Django with a legacy database https://docs.djangoproject.com/en/2.1/howto/legacy-databases/
How to add multiple databases to the django application? http://books.agiliq.com/projects/django-orm-cookbook/en/latest/multiple_databases.html
Wordpress on Django https://stackoverflow.com/questions/6344022/wordpress-on-django/10060600#10060600
Django: using more than one database with inspectdb? https://stackoverflow.com/questions/37581885/django-using-more-than-one-database-with-inspectdb
Wordpress and Django co-existing? https://www.reddit.com/r/django/comments/39fzgc/wordpress_and_django_coexisting/
Howto: add a legacy database to Django http://harringr.co/Django-legacy-databases/
How to Configure Multiple Databases in Django the Simple Way https://strongarm.io/blog/multiple-databases-in-django/
multiple databases and multiple models in django https://stackoverflow.com/questions/18547468/multiple-databases-and-multiple-models-in-django
설치된 앱에 teamgalois 를 추가하고, 장고 생성시 기본적으로 만들어지는 데이터베이스는 그냥 두고, 워드프레스 접속 정보를 추가한다. 그리고 라우터 파일을 수정하여 모델의 라벨링에 따라 접속할 데이터베이스를 지정한다.
/home/founder/teamgalois/teamgalois/settings.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'teamgalois', ] try: import pymysql pymysql.install_as_MySQLdb() except: pass DATABASE_ROUTERS = ['teamgalois.routers.DatabaseAppsRouter'] DATABASE_APPS_MAPPING = {'contenttypes': 'default', 'auth': 'default', 'admin': 'default', 'sessions': 'default', 'messages': 'default', 'staticfiles': 'default', 'teamgalois': 'wp', } DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }, 'wp': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'redsparrow', 'USER': '**************', 'PASSWORD': '*****************', 'HOST': 'localhost', # Or an IP Address that your DB is hosted on 'PORT': '3306', } } | cs |
/home/founder/teamgalois/teamgalois/routers.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | from django.conf import settings class DatabaseAppsRouter(object): """ A router to control all database operations on models in the user application. """ def db_for_read(self, model, **hints): """ Attempts to read user models go to users_db. """ if model._meta.app_label == 'teamgalois': return 'wp' return None def db_for_write(self, model, **hints): """ Attempts to write user models go to users_db. """ if model._meta.app_label == 'teamgalois': return 'wp' return None def allow_relation(self, obj1, obj2, **hints): """ Allow relations if a model in the user app is involved. """ if obj1._meta.app_label == 'teamgalois' or \ obj2._meta.app_label == 'teamgalois': return True return None def allow_migrate(self, db, app_label, model_name=None, **hints): """ Make sure the auth app only appears in the 'users_db' database. """ if app_label == 'teamgalois': return db == 'wp' return None | cs |
여기까지 한 후 inspectdb 를 통해서 장고 모델을 자동으로 생성한다.
1 | ~/teamgalois$ python manage.py inspectdb --database=wp > teamgalois/models.py | cs |
아래와 같이 생성이 되었다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # This is an auto-generated Django model module. # You'll have to do the following manually to clean this up: # * Rearrange models' order # * Make sure each model has one field with primary_key=True # * Make sure each ForeignKey has `on_delete` set to the desired behavior. # * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table # Feel free to rename the models, but don't rename db_table values or field names. from django.db import models class WpBpActivity(models.Model): id = models.BigAutoField(primary_key=True) user_id = models.BigIntegerField() component = models.CharField(max_length=75) type = models.CharField(max_length=75) action = models.TextField() content = models.TextField() primary_link = models.TextField() item_id = models.BigIntegerField() secondary_item_id = models.BigIntegerField(blank=True, null=True) date_recorded = models.DateTimeField() hide_sitewide = models.IntegerField(blank=True, null=True) mptt_left = models.IntegerField() mptt_right = models.IntegerField() is_spam = models.IntegerField() class Meta: managed = False db_table = 'wp_bp_activity' | cs |
이제 워드프레스 테이블 데이터 조회 및 수정, 삭제 등이 정상적으로 되는지 확인하기 위해 장고 관리자를 생성하고, 장고 어드민에 테이블 하나를 추가해서 테스트를 진행하자. 아래에서 보다시피 이와 관련된 테이블이 마이그레이션 되지 않은 상태이다.
1 2 | django.db.utils.ProgrammingError: (1146, "Table 'redsparrow.auth_user' doesn't exist") | cs |
마이그레이션을 진행한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | ~/teamgalois$ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying sessions.0001_initial... OK | cs |
그리고 관리자를 생성한다.
1 2 3 4 5 6 | ~/teamgalois$ python manage.py createsuperuser Username (leave blank to use 'root'): root Email address: ***********@gmail.com Password: Password (again): Superuser created successfully. | cs |
관리자로 정상 로그인이 됨을 알 수 있다.
이제 admin.py 파일을 수정하여 데이터 조회, 생성, 삭제 등의 기능이 정상 작동하는지 확인하자.
/home/founder/teamgalois/teamgalois/admin.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # -*- coding: utf-8 -*- from django.contrib import admin # from django.contrib.admin import AdminSite from django.contrib.admin.templatetags.admin_list import date_hierarchy from teamgalois.models import WpComments # class AdminBase(admin.ModelAdmin): # # def natural_title(self, obj): # return unicode(obj) # # natural_title.short_description = 'Title' class AdminWpComments(admin.ModelAdmin): model = WpComments fieldsets = [ (None, {'fields': ['comment_post_id']}), (None, {'fields': ['comment_author']}), (None, {'fields': ['comment_author_ip']}), (None, {'fields': ['comment_date']}), (None, {'fields': ['comment_date_gmt']}), (None, {'fields': ['comment_content']}), (None, {'fields': ['comment_karma']}), (None, {'fields': ['comment_approved']}), (None, {'fields': ['comment_agent']}), (None, {'fields': ['comment_parent']}), (None, {'fields': ['user_id']}), ] list_display = ('comment_id', 'comment_post_id', 'comment_author','comment_date', 'comment_date_gmt' ,'comment_karma','comment_approved','comment_parent','user_id' ) search_fields = ['comment_content'] ordering = ('-comment_id',) admin.site.register(WpComments,AdminWpComments) | cs |
여기서 필드셋에 pk 인 comment_id 를 추가하게 되면 다음과 같은 OperationalError 가 발생하니 주의한다. 넣고 싶으면 readonly 처리를 해줘야한다.
1 | (None, {'fields': ['comment_id']}), | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | OperationalError at /admin/teamgalois/wpcomments/ no such table: wp_comments Request Method: GET Request URL: http://www.teamgalois.com:8000/admin/teamgalois/wpcomments/ Django Version: 2.1.3 Exception Type: OperationalError Exception Value: no such table: wp_comments Exception Location: /home/founder/anaconda3/envs/dominika/lib/python3.7/site-packages/django/db/backends/sqlite3/base.py in execute, line 296 Python Executable: /home/founder/anaconda3/envs/dominika/bin/python Python Version: 3.7.1 Python Path: ['/home/founder/teamgalois', '/home/founder/anaconda3/envs/dominika/lib/python37.zip', '/home/founder/anaconda3/envs/dominika/lib/python3.7', '/home/founder/anaconda3/envs/dominika/lib/python3.7/lib-dynload', '/home/founder/anaconda3/envs/dominika/lib/python3.7/site-packages'] Server time: Mon, 12 Nov 2018 09:28:14 +0000 | cs |
이제 해당 테이블을 장고 관리자에서 확인할 수 있고, 삭제 등의 기능도 정상적으로 작동함을 알 수 있다.
phpMyAdmin 사이트에서도 해당 코멘트가 삭제되어 있음을 알 수 있다.
'프로그래밍 Programming' 카테고리의 다른 글
Debian 버전 체크하기 (0) | 2018.11.24 |
---|---|
브라우저에서 구글 클라우드 플랫폼 주피터 노트북 실행하기 (0) | 2018.11.15 |
워드프레스 이미지 업로드 사이즈 수정하기 (Nginx) (0) | 2018.11.11 |
파이썬을 통한 MySQL 접속 Python MySQL Database Connection (0) | 2018.11.10 |
우분투 18.04 에 Nginx phpMyAdmin 설치하기 Installing phpMyAdmin for Nginx on Ubuntu 18.04 (0) | 2018.11.09 |