python.django - k821209/pipelines GitHub Wiki

django react, ssl

server{
        # listen 8888;
        listen 8889 ssl;
        # proxy_ssl_server_name on;

        #ssl_password_file /etc/nginx/ssl/pw.txt;
        ssl_certificate /etc/nginx/ssl/cert.crt;
        ssl_certificate_key /etc/nginx/ssl/cert.key;

        ssl_session_timeout 5m;
        #ssl_protocols SSLv2 SSLv3 TLSv1;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        server_name tools.gnu.ac.kr;
        client_max_body_size 5000M;

        root /data;
        location /api {
                proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect off;
               if (!-f $request_filename) {
                        proxy_pass http://0.0.0.0:5000;
                        break;
                        }
                }
        location /static_django/ {
            alias /data/static/;
            #proxy_pass http://0.0.0.0:5000; # debug = False ํ•˜๊ณ  ๋‚˜์„œ๋Š” proxy_pass๋ฅผ ์—†์• ์ฃผ์ž. ์žฅ๊ณ ๋ฅผ ํ†ตํ•ด์„œ static์„ ์„œ๋น™ ์•ˆํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค
        }
        location /media/ {
            alias /data/media/;
            #proxy_pass http://0.0.0.0:5000; #
        }
        location / {
            root   /data/gnurdb/build;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

}
# SSL ์„ค์ •ํ•˜๊ณ  server nginx restart ์‹œ์— ๋‹ค์Œ์ด ๋œฌ๋‹ค. ๋น„๋ฒˆ์€ ์—…์ฒด์— ๋ฌธ์˜ !!! 
Enter PEM pass phrase:

django, react, ํ•˜๋‚˜์˜ ํฌํŠธ

server{
        listen 8888;
        server_name thisApp;
        client_max_body_size 5000M;
        root /data;
        location /api {
                proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect off;
               if (!-f $request_filename) {
                        proxy_pass http://0.0.0.0:5000;
                        break;
                        }
                }
        location /static_django {
            root /data/static;
            proxy_pass http://0.0.0.0:5000; #
        }
        location /media {
            root /data/media;
            proxy_pass http://0.0.0.0:5000; #
        }
        location / {
            root   /data/reactapp/build;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

}
# /data/omics-react/build

#server {
#  listen 8888;
#  location / {
#    root   /data/gnurdb/build;
#    index  index.html index.htm;
#    try_files $uri $uri/ /index.html;
#  }
#}
# setting.py

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
FILE_UPLOAD_MAX_MEMORY_SIZE = 5242880000  # 5 MB
# STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# STATIC_ROOT = '/static/'
STATIC_URL = '/static_django/'
print(BASE_DIR)
# main:urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from app.views import Researcher_view
from rest_framework import routers
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.static import static
from django.conf import settings



router = routers.DefaultRouter()
router.register('Researcher', Researcher_view)

urlpatterns = [
    path('api/admin/', admin.site.urls),
    # url(r'^', include(router.urls)),
    path('api/', include(router.urls)),
    path('markdownx/', include('markdownx.urls')),
]

urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL,
                      document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL,
                              document_root=settings.STATIC_ROOT)

print(urlpatterns)

login ๊ตฌํ˜„

# https://developer0809.tistory.com/98
conda install -yc conda-forge django-allauth
conda install -yc conda-forge  django-rest-auth
conda install -yc conda-forge django-cors-headers
conda install -yc conda-forge django-filter
conda install -yc conda-forge djangorestframework

error

# ValueError: The field admin.LogEntry.user was declared with a lazy reference to 'recommend.authuser', but app 'recommend' doesn't provide model 'authuser'
# https://stackoverflow.com/questions/50324561/valueerror-the-field-admin-logentry-user-was-declared-with-a-lazy-reference/65112242
# ์—ฐ๊ด€๋œ admin์ด๋‚˜ ํผ์„ ๋ชจ๋‘ ์ฝ”๋ฉ˜ํŠธ ์•„์›ƒ ํ•˜๊ณ 
# comment AUTH_USER_MODEL in settings.py so it points to default User model
python manage.py migrate auth zero
# uncomment to be AUTH_USER_MODEL='recommend.AuthUser'
python manage.py migrate auth
python manage.py migrate appname 
python manage.py migrate 

patch

์•ˆ๋…•ํ•˜์„ธ์š”. ์—ฌ๊ธฐ์ €๊ธฐ ํ—ค๋งค๋‹ค๊ฐ€ ์งˆ๋ฌธ์„ ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค. 
DRF๋กœ API๋งŒ๋“ค๊ณ  React๋กœ API๋ฅผ ๋ถˆ๋Ÿฌ์„œ ํ™”๋ฉด์— ๋„์šฐ๊ณ  ์ž…๋ ฅ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ DRF์— axios๋กœ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋Š” ๊ตฌ์„ฑ์„ ๋งŒ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ModelViewSet์„ ์จ์„œ view๋ฅผ ๊ตฌ์„ฑํ–ˆ๋”๋‹ˆ ๋ณ„ ๋ฌด๋ฆฌ์—†์ด axios.patch๋กœ ์ž…๋ ฅ๋ฐ›์€ ๊ฐ’์„ ๋””๋น„์— ์—…๋ฐ์ดํŠธํ•˜๋Š”๊ฒŒ ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. 
์กฐ๊ธˆ ๋‹ค๋ฅธ ๋‹ˆ์ฆˆ๊ฐ€ ์žˆ์–ด์„œ ์›น์—์„œ axios๋กœ ์—…๋ฐ์ดํŠธ ํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ, ํŒŒ์ด์ฌ์—์„œ requests ๋ชจ๋“ˆ์„ ์จ์„œ ๋˜‘๊ฐ™์ด patch๋กœ ๋””๋น„๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•˜๋ ค๋‹ˆ Method Not Allowed ๊ฐ€ ๋œน๋‹ˆ๋‹ค. 
ํŒŒ์ด์ฌ์—์„œ ์“ฐ๋Š” requests๋ชจ๋“ˆ๊ณผ ๋ฆฌ์—‘ํŠธ์˜ axios๊ฐ€ ํ•˜๋Š”์ผ์ด ๋‹ค๋ฅธ๊ฑด์ง€์š”. ํŒŒ์ด์ฌ์—์„œ patch๋ฅผ ํ†ตํ•ด ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋ ค๋ฉด ์–ด๋–ค ๋ฐฉ๋ฒ•์„ ์จ์•ผํ• ๊นŒ์š” 
๋ฏธ๋ฆฌ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
์•Œ์•„๋ƒˆ์Šต๋‹ˆ๋‹ค. ;; axios์—์„œ๋Š” url์„ ~~~~/?auto_id=1์ด๋ ‡๊ฒŒ ์ฃผ๊ณ  param์„ ์ค˜๋„ ํฐ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ๋Š”๋ฐ python requests์—์„œ๋Š” url ์„ ~~~~/1/ ์ด๋Ÿฐ๋ชจ์–‘์œผ๋กœ ์ฃผ๊ณ  param์„ ์ค˜์•ผํ•˜๋Š”๊ฒƒ์ด๊ตฐ์š”! https://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/?fbclid=IwAR2DthW_8vfuzb3WZXcePoQcuqtkw5eDaY8YCxykZONrjg5AfKxWtjOeDDk

django debug=false ์„ค์ •์„ ์œ„ํ•œ static ์„ธํŒ… ํ™•์ธ

django api setting

https://www.django-rest-framework.org/#installation

# cors
conda install -yc conda-forge django-cors-headers
INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)
MIDDLEWARE_CLASSES = (
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
)

django 3 suit install

> pip install https://github.com/darklow/django-suit/tarball/v2

๋Œ€์šฉ๋Ÿ‰ํŒŒ์ผํ—ˆ์šฉ

# nginx.config
...
client_max_body_size 5000M;
...
# django setting.py

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
FILE_UPLOAD_MAX_MEMORY_SIZE = 5242880000  # 5 MB
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

FILE_UPLOAD_MAX_MEMORY_SIZE = 5242880000 # 5 MB
$ service nginx reload

์žฅ๊ณ ,gunicorn,nginx

project๋ช… : RNAseqDB

# urls.py
# static ์„ gunicorn์ด ๋ถˆ๋Ÿฌ์˜ค๋ ค๋ฉด ์ด๋Ÿฐ ์„ค์ •์ด ํ•„์š” 
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.static import static
from django.conf import settings

...

urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL,
                      document_root=settings.MEDIA_ROOT)
# settings.py
# wsgi ํ• ๋ ค๋ฉด static ์„ค์ •ํ•ด์•ผํ•จ 
echo "STATIC_ROOT = os.path.join(BASE_DIR, 'static')" >> RNAseqDB/settings.py
python manage.py collectstatic
drwxr-xr-x 5 root root     160 Jul  1 03:31 ./
drwxr-xr-x 6 root root     149 Jul  1 03:22 ../
drwxr-xr-x 2 root root       6 Jul  1 03:31 .empty/
drwxr-xr-x 4 root root     203 Jul  1 03:19 RNAseqAPI/
drwxr-xr-x 3 root root     117 Jul  1 03:19 RNAseqDB/
-rw-r--r-- 1 root root    1045 Jul  1 03:19 csv2sql.py
-rw-r--r-- 1 root root 3760128 Jul  1 03:19 db.sqlite3
-rw-r--r-- 1 root root     540 Jul  1 03:19 manage.py
-rw-r--r-- 1 root root 4986701 Jul  1 03:19 sarco_count.pk
/data/RNAseqDB/RNAseqDB# gunicorn --bind 0.0.0.0:8000 RNAseqDB.wsgi
  • nginx ๋Š” flask ๋ฐฉ์‹์„ ๋”ฐ๋ฅด๋ฉด ๋œ๋‹ค.
server{
        listen 8888;
        server_name thisApp;
        client_max_body_size 5000M;
        root /data/forestDB;
        location / {
                proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect off;
               if (!-f $request_filename) {
                        proxy_pass http://0.0.0.0:5000;
                        break;
                        }
                }
        location /static{
            alias /data/forestDB/static;
            proxy_pass http://0.0.0.0:5000; #
        }
        location /media{
            alias /data/forestDB/media;
            proxy_pass http://0.0.0.0:5000; #
        }
}

์žฅ๊ณ ์•„ํŒŒ์น˜์—ฐ๋™

  • ์žฅ๊ณ  view ์—์„œ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋“ค์€ (csv๊ฐ™์€๊ฒƒ) ์€ ์ ˆ๋Œ€๊ฒฝ๋กœ๋กœ ๋ถˆ๋Ÿฌ์™€์•ผํ•จ.
  • upload ํ•˜๋Š” static folder๊ฐ™์€๊ฑด chmod 777 ํ•ด์ฃผ์‚ผ
  • ํŠนํžˆ apache ๊ฐ€ ์ ‘๊ทผํ•  staticํด๋”์— ๊ผญ chmod 777
  • DB ํŒŒ์ผ๋“ค์ด ์žˆ๋Š” basedir ๋„ ๊ผญ chmod 777, ํŒŒ์ผ๋“ค๋„ ํ•ด์•ผํ•˜๋Š”์ง€๋Š” ์ž˜ ๋ชจ๋ฅด์ง€๋งŒ ์—๋Ÿฌ๋‚˜๋ฉด ํ•ด๋ณด๊ธธ.
  • apache2 ์„ค์น˜
  • ์•„ํŒŒ์น˜ ์‹คํ–‰ํ•˜๋ฉด์„œ ๋‚˜๋Š” ์—๋Ÿฌ๋“ค์€ cat /var/log/apache2/error.log
  • apt-get install libapache2-mod-wsgi-py3
  • ์ ‘์†๋˜๋Š”์ง€ ํ™•์ธ. ์ผ๋‹จ 80 ํฌํŠธ ๊ธฐ๋ณธ์œผ๋กœ ์“ธ ๊ฑฐ๊ธฐ ๋•Œ๋ฌธ์— 8888์œผ๋กœ ๋ฐ”๊พธ๋Š” ์ง“์„ ํ•˜์ง€๋ง์ž
  • ๊ธฐ๋ณธ ์ ‘์† ํฌํŠธ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€ /etc/apache2/ports.conf์— ์žˆ๋‹ค. Listen ์–ด์ฉŒ๊ณ ..
  • /etc/apache2/sites-available/ ์— ์•„ํŒŒ์น˜ ํ˜ธ์ŠคํŒ…์˜ ๊ธฐ๋ณธ์„ค์ •์ด ์žˆ๋‹ค.
  • pglhome.conf ๊ฐ™์€๊ฑธ ๋งŒ๋“ค์–ด๋†“๊ณ 
> a2dissite 000-default # ๊ธฐ๋ณธ ์ ‘์† ํ™”๋ฉด์„ ๊ธˆ์ง€ ์‹œํ‚ด.  
> a2ensite pglhome      # ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ์žฅ๊ณ ๋ฅผ ๋งตํ•‘ ์‹œํ‚ฌ ์ฝ˜ํ”ผ๊ทธ 
  • ํ•˜๋ฉด pglhome.conf์˜ ์„ค์ •์œผ๋กœ ์•„ํŒŒ์น˜๊ฐ€ ์‹œ์ž‘๋˜๊ฒŒ ๋œ๋‹ค.
  • ๊ทธ๋Ÿฌ๋ฏ€๋กœ pglhome.conf๋ฅผ ์„ค์ •ํ•ด์•ผํ•œ๋‹ค.
# pglhome.conf
<VirtualHost *:80>
        WSGIDaemonProcess pgl.gnu.ac.kr threads=10 python-home=/home/k821209/PGL_page/:/usr/local/lib/python3.5/dist-packages/
        WSGIProcessGroup pgl.gnu.ac.kr
        WSGIScriptAlias / /home/k821209/PGL_page/pgl/wsgi.py process-group=pgl.gnu.ac.kr


        <Directory /home/k821209/PGL_page/pgl/>
                <Files wsgi.py>
                        Require all granted
                </Files>
        </Directory>

        Alias /files/ /home/k821209/PGL_page/files/
        Alias /static/ /home/k821209/PGL_page/static/
        <Directory /home/k821209/PGL_page/files>
            Require all granted # ์ตœ์‹ ๋ฒ„์ „์€ ๊ผญ ์ด๋ ‡๊ฒŒ ํ•ด์ค˜์•ผํ•จ allow ์–ด์ฉŒ๊ณ  ํ•˜๋Š”๊ฑด ์˜›๋ฒ„
        </Directory>
        <Directory /home/k821209/PGL_page/static> # ์•ž์œผ๋ก  ์—ฌ๊ธฐ๋‹ค ๊ฒฐ๊ณผํŒŒ์ผ์„ ์ง‘์ ํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜จ๋‹ค. 
            Require all granted
        </Directory>
</VirtualHost>

**Link to self **

<a class="item" href="{% url 'network:index' %}" target="_blank"> # network ๋ผ๋Š” ์ด๋ฆ„์€ url์— ์ •์˜ ๋˜์–ด ์žˆ์Œ 
                    <button class="ui fluid button">
                        LINK
                    </button>
                </a>

Multiple DB

# setting.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
               },
    'soyped': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'soyped.sqlite3'),
               },
    'lemna_tandemDB': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'lemna_tandemDB.sqlite3'),
               },
}
DATABASE_ROUTERS = ['lemna_tandem.router.lemna_Router','SoyPed.router.SP_Router']

# router.py # in app directory
class lemna_Router(object):
    def db_for_read(self, model, **hints):
        "Point all operations on SoyPed models to 'soyped'"
        if model._meta.app_label == 'lemna_tandem':
            return 'lemna_tandemDB'
        return None # ์ด๊ฒŒ ๊ผญ ๋„Œ์ด ๋˜์–ด์ค˜์•ผํ•œ๋‹ค.. ๊ทธ๋ž˜์•ผ ์•„๋‹๊ฒฝ์šฐ ๋‹ค์Œ ํ•ญ๋ชฉ์œผ๋กœ ๋„˜์–ด๊ฐ„๋‹ค... ์ด๋Ÿฐ์  ์žฅํ•  ์ด๊ฒƒ๋•Œ๋ฌธ์— ๋‚ด๊ฐ€ 

    def db_for_write(self, model, **hints):
        "Point all operations on SoyPed models to 'soyped'"
        if model._meta.app_label == 'lemna_tandem':
            return 'lemna_tandemDB'
        return None # None ์œผ๋กœ ์•ˆํ•ด์ฃผ๊ณ  default๋กœ ๋Œ๋ฆฌ๋ฉด ๋‹ค์Œ ๋ผ์šฐํ„ฐ๊ฐ€ ์ผ์„ ๋ชปํ•œ๋‹ค. ๋ฌด์กฐ๊ฑด None์„ ํ•˜๊ณ  setting.py ์ˆœ์„œ์ƒ ๋งˆ์ง€๋ง‰ router์—๋Š” default return์„ ํ•ด์ค˜๋„ ๋œ๋‹ค 

    def allow_relation(self, obj1, obj2, **hints):
        "Allow any relation if a both models in chinook app"
        if obj1._meta.app_label == 'lemna_tandem' and obj2._meta.app_label == 'lemna_tandem':
            return True
        # Allow if neither is chinook app
        elif 'lemna_tandem' not in [obj1._meta.app_label, obj2._meta.app_label]:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Make sure the auth app only appears in the 'auth_db'
        database.
        """
        if app_label == 'lemna_tandem':
            return db == 'lemna_tandemDB'
        return None
    def allow_syncdb(self, db, model):
        if db == 'lemna_tandemDB' or model._meta.app_label == "lemna_tandem":
            return False # we're not using syncdb on our legacy database
        else: # but all other models/databases are fine
            return True

https://beomi.github.io/python/2017/02/08/Setup-SocialAuth-for-Django.html

Build DB

django-admin startproject mysite .
python manage.py migrate
python manage.py runserver 0.0.0.0:8000
manage.py flush --database DB_NAME # ๋””๋น„ ๋‚ ๋ฆฌ๊ธฐ
# DB์ž‘์„ฑ์‹œ์ž‘. 
python manage.py startapp blog # ์ดํ›„ mysite/setting.py INSTALLED_APP ์— blog ์ถ”๊ฐ€

urls

mysite/urls.py ์— ๋‹ค์Œ์„ ์ถ”๊ฐ€

url(r'^blog/', include('blog.urls'))
path('kkd2/',include('kkd2.urls'))

blog/urls.py ์— ๋‹ค์Œ์„ ์ถ”๊ฐ€

from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^$', views.post_list, name='post_list'),
    
]

view

blog/view.py ์— ๋‹ค์Œ์„ ์ถ”๊ฐ€.

def post_list(request):
        return render(request, 'blog/post_list.html', {}) 
# url์—์„œ view.post_list๋ฅผ ๋ถ€๋ฅด๋ฉด blog/post_list.html์„ ๋ถ€๋ฅธ๋‹ค. ๋ถ€๋ฅผ๋•Œ {}์•ˆ์— ๋ณ€์ˆ˜๋ฅผ ๋ณด๋‚ด์ค€๋‹ค. ํ•ด๋‹น ๋ณ€์ˆ˜๋Š” model.py ์—์„œ ๊ฐ€์ ธ์˜ค๊ฒŒ๋จ.  
from django.shortcuts import render
from .models import DBmodel
def index(request):
        DBex    = DBmodel.objects.order_by('?')[0:2] # ๋ Œ๋ค์œผ๋กœ ํด๋ ˆ์Šค๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. 
        return render(request, 'CreDB/index.html', {'DBex' : DBex}) # ๋ Œ๋ค์œผ๋กœ ๊ฐ€์ ธ์˜จ ํด๋ ˆ์Šค๋ฅผ html๋กœ ๋ณด๋‚ธ๋‹ค. 

model class field๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ.

...
DBex          = DBmodel.objects.order_by('?')[0] # ํ•˜๋‚˜๋งŒ ์„ ํƒํ•ด๋†จ์Œ. 
final_comp_ex = final_comp.objects.get(transcriptname=DBex.genename) # DBex ๋ผ๋Š” ๋ชจ๋ธ ํด๋ ˆ์Šค์˜ genename ํ•„๋“œ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์™€๋ผ. 
...

form class field๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ

class NameForm_plain(forms.Form): # view ์•ˆ์—์„œ ๊ทธ๋ƒฅ ์„ ์–ธ์„ ํ•จ. 
    transcript_name = forms.CharField(label='transcript name', max_length=50)
def index(request):
        DBex          = DBmodel.objects.order_by('?')[0]
        final_comp_ex = final_comp.objects.get(transcriptname=DBex.genename)
        if request.method=='POST':
            form = NameForm_plain(request.POST)
            if form.is_valid():
                query = form.cleaned_data['transcript_name'] # ์ฟผ๋ฆฌ๋ผ๋Š” ๋ณ€์ˆ˜์— ํผ์—์„œ ๋ฐ›์€ ๊ฐ’์„ ๋„ฃ์–ด์ค€๋‹ค. ํด๋ ˆ์Šค์˜ ๋ณ€์ˆ˜๋ช…์ด ๋”•์…”๋„ˆ๋ฆฌ์˜ ํ‚ค๊ฐ’์œผ๋กœ ๋ณ€์‹ ํ•œ๊ฒƒ์— ์ฃผ๋ชฉ. ๋ชจ๋ธ ํด๋ ˆ์Šค์™€ ๋‹ค๋ฅด๋‹ค.
...

๊ฒ€์ƒ‰๋ฒ„ํŠผ ๋„ฃ๊ธฐ

from django.shortcuts import render
from django import forms
from .models import DBmodel
class NameForm(forms.ModelForm):
    class Meta:
        model = DBmodel
        fields = ('genename',)
def index(request):
        DBex       = DBmodel.objects.order_by('?')[0]
        if request.method=='POST':
            form = NameForm(request.POST)
            if form.is_valid():
                query = form.cleaned_data['genename']
                DBex = DBmodel.objects.get(genename=query)
                form = NameForm()
                return render(request, 'CreDB/index.html', {'DBex' : DBex, 'form': form})
                #return redirect('',query=genename)
        else:
            form = NameForm()
            return render(request, 'CreDB/index.html', {'DBex' : DBex, 'form': form})
#๊ฒ€์ƒ‰๋ฒ„ํŠผ์„ ๋„ฃ์„์ž๋ฆฌ์—
<form method=POST>
{% csrf_token %}
{{form}}
<input type="submit" value="Submit"/>
</form>

model

blog/model.py ์— ๋‹ค์Œ์„ ์ถ”๊ฐ€

# model.py
class Post(models.Model):
        author = models.ForeignKey('auth.User')
        title = models.CharField(max_length=200)
        text = models.TextField()
        created_date = models.DateTimeField(
                default=timezone.now)
        published_date = models.DateTimeField(
                blank=True, null=True
        def publish(self):
            self.published_date = timezone.now()
            self.save()
        def __unicode__(self):  # __str__ ๋Œ€์‹ ์— ์ด๋ ‡๊ฒŒ ํ•ด์ค€๋‹ค. 
            return self.title

๋ชจ๋ธ์„ ์ž‘์„ฑํ•˜๊ณ ๋Š” ๊ผญ

# ์‚ฌํ›„์— ๋ชจ๋ธ์— field๋ฅผ ์ถ”๊ฐ€ํ•˜๋”๋ผ๋„, ๋‹ค์Œ์„ ์‹คํ–‰ํ•ด์ฃผ๋ฉด๋œ๋‹ค. ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์„ ๋•Œ ๋””ํดํŠธ ๊ฐ’์„ ์ฃผ๋ผ๊ณ  ๊ฒฝ๊ณ ๋ฅผ ์ค„๊ฒƒ์ธ๋ฐ, ์•”๊ฒƒ์ด๋‚˜์ฃผ๋ฉด๋œ๋‹ค. 
python manage.py makemigrations blog 
python manage.py migrate blog
# app/admin.py
from django.contrib import admin
from .models import DBmodel
admin.site.register(DBmodel)

์›ํ•˜๋Š” ํ…Œ์ด๋ธ”์„ ๋ชจ๋ธ์— ์‘ค์…”๋„ฃ์„๋•Œ ๊ฐœ์ธ์ ์œผ๋กœ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์งœ๋Š”๊ฒŒ ํŽธํ•œ๋“ฏ.

# django script running 
./manage.py shell < myscript.py
# ํ˜น์€
./manage.py shell
>>> execfile('myscript.py')

myscript.py

from CreDB.models import DBmodel
file_in = 'all.merged.bam.transcripts.all.txt'
for line in open(file_in):
    cell = line.strip().split('\t')
    DBmodel.objects.create(genename=cell[0], cov_1x=cell[1], cov_10x=cell[2], cov_30x=cell[3],depth_ratio=cell[4],depth=cell[5],match=cell[6],match_ratio=cell[7])
posts = DBmodel.objects.all()
for post in posts:
    post.publish()

์‚ฌํ›„์— ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์„๋•Œ

# ๋‹ค์Œ์„ ์•Œ์•„์„œ ๋ฃจํ”„๋ฅผ ๋Œ๋ฆฌ๋“  ํ•จ. 
DBmodel.object.filter(genename="name").update(newfield="ATGC")

html

css #~/static/css/CreDB.css ๋ผ๋Š” ํŒŒ์ผ์„ ๋งŒ๋“ ๋‹ค.

#table ํ˜•์‹ ํ…Œ์ด๋ธ”์„ ๋„ฃ์„๋•Œ๋Š” ์ด๊ฑธ๋กœ ๊ณ ์ •ํ•˜๋Š”๊ฒŒ ์ข‹์€๋“ฏ. 
table {
       width: 60%;
      }
td, th {
        border: 2px solid #dddddd;
        text-align: left;
        padding: 8px;
       }
tr:nth-child(even) {
                   background-color: #dddddd;
                   }
#body ํฐํŠธ ๋ฐ ๊ธฐํƒ€๋“ฑ๋“ฑ
body {
     font-family: "Times New Roman", Times, serif;
     padding-left: 15px;
     }
# ๊ธฐํƒ€๋“ฑ๋“ฑ ๋งŽ์€๊ฒƒ๋“ค์€ w3school๊ฐ€๋ฉด ๋งŽ์Œ. 
# css๋ฅผ ์ ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ ํ•ญ๋ชฉ์ด ๋“ค์–ด๊ฐ€์•ผํ•œ๋‹ค. 
{% load staticfiles %}
<html>
<head>
<link rel="stylesheet" href="{% static 'css/CreDB.css' %}">
</head>
#๊ฐ€๋กœ์ค„ ๋„ฃ์„๋•Œ
<hr style="border: dotted 2px gray;">
#ํ…Œ์ด๋ธ”๋งŒ๋“ค๋•Œ
<table>
         <tr>
          <th>Cov.1x</th>
          <th>Cov.10x</th>
          <th>Cov.30x</th>
          <th>Depth.ratio</th>
          <th>Cov.1x.match</th> # table header
         </tr>
         <tr>
          <td>{{DBex.cov_1x}}</td>
          <td>{{DBex.cov_10x}}</td>
          <td>{{DBex.cov_30x}}</td>
          <td>{{DBex.depth_ratio}}</td>
          <td>{{DBex.match_ratio}}</td> # table values
        </table>
# ๊ธ€์ƒ์ž (์‹œํ€€์Šค ์ƒ์ž)
<textarea cols="100" rows="5">
        {{DBex.CDS}}
</textarea>
# ์ˆ˜์ •์‚ฌํ•ญ ๋ฐ˜์˜
python manage.py makemigrations blog 
# ์ˆ˜์ •์‚ฌํ•ญ ์ ์šฉ
python manage.py migrate blog
# ๊ด€๋ฆฌ์ž ์•„์ด๋”” ํŒŒ๊ธฐ. 
python manage.py createsuperuser

ํ•œ๊ธ€ ์ž…๋ ฅ๋ฌธ์ œ (python2)

# model.py
class Post(models.Model):
        author = models.ForeignKey('auth.User')
        title = models.CharField(max_length=200)
        text = models.TextField()
        created_date = models.DateTimeField(
                default=timezone.now)
        published_date = models.DateTimeField(
                blank=True, null=True)

        def publish(self):
            self.published_date = timezone.now()
            self.save()

        def __unicode__(self):  # __str__ ๋Œ€์‹ ์— ์ด๋ ‡๊ฒŒ ํ•ด์ค€๋‹ค. 
            return self.title

basic commands

# run server
~/django/mysite$ python manage.py runserver 0.0.0.0:8000
# build webapp named "polls"
~/django/mysite$ python manage.py startapp polls
# configure webapp
~/django/mysite/polls$ vi models.py 
# migration of webapp
~/django/mysite$ python manage.py makemigrations polls
# migration
~/django/mysite$ python manage.py sqlmigrate polls 0001
~/django/mysite$ python manage.py migrate
# edit the "poll/model.py"
from django.db import models
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
  • model.Model์€ ํด๋ ˆ์Šค ๋ณ€์ˆ˜๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ, ๊ฐ ๋ณ€์ˆ˜๋“ค์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ Field์— ํ•ด๋‹นํ•จ.
  • model.CharField : ๋ฌธ์ž๋กœ ๊ตฌ์„ฑ๋œ ํ•„๋“œ
  • model.DateTimeField : ๋‚ ์งœ ์‹œ๊ฐ„ ํ•„๋“œ
  • ๋ณ€์ˆ˜๋ช…์ด ์ฃผ๋กœ ๊ฐ ํ•„๋“œ๋ช…์ด ๋จ. ํ•„๋“œ๋ช…์„ ์ง€์ •ํ•ด์ฃผ๋ ค๋ฉด models.DateTimeField('date published') ๊ณผ ๊ฐ™์ด ์ฒซ๋ฒˆ์งธ ์ž…๋ ฅ๊ฐ’์œผ๋กœ ์ง€์ •ํ•ด์คŒ
  • models.CharField(max_length=200) ์˜ ๊ฒฝ์šฐ๋Š” max_length๊ฐ’์„ ์ง€์ •ํ•ด์ค˜์•ผํ•จ (ํ•„์ˆ˜).
  • models.DecimalField(max_digits=4, decimal_places=3) : ์ˆซ์ž ํ•„๋“œ. ํ•ด๋‹น ์ผ€์ด์Šค๋Š” 1.000 ๊ฐ™์€ ์ˆ˜๊ฐ€ ํ•ด๋‹น
  • models.TextField() : ๊ธ€๋ฅ˜. ์‹œํ€€์Šค ๋ฐ•์œผ๋ฉด ๋”ฑ.
# app migration (make)
~/django/mysite$ python manage.py makemigrations polls
# migration run
~/django/mysite$ python manage.py migrate

django์—์„œ๋Š” class myname(model.Model): ๊ณผ ๊ฐ™์€ ๋ชจ์–‘์„ ๋งŽ์ด ์“ฐ๊ฒŒ ๋˜๋Š”๋ฐ model.Model์ด๋ผ๋Š” class๋ฅผ ๋‚ด๊ฐ€ ์ง€์ •ํ•œ ํด๋ ˆ์Šค ์ด๋ฆ„์œผ๋กœ ๋ถˆ๋Ÿฌ์˜จ๋’ค์— model.Model์— ์žˆ๋Š” ๋ณ€์ˆ˜๋“ค์„ ์„ค์ •ํ•˜๋Š” ์ž‘์—…์„ ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ํŽธํ•˜๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ