├── .gitignore ├── 04_bookmark ├── bookmark │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── bookmark │ │ │ ├── bookmark_confirm_delete.html │ │ │ ├── bookmark_create.html │ │ │ ├── bookmark_detail.html │ │ │ ├── bookmark_list.html │ │ │ └── bookmark_update.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── config │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── static │ └── style.css ├── static_files │ ├── admin │ │ ├── css │ │ │ ├── autocomplete.css │ │ │ ├── base.css │ │ │ ├── changelists.css │ │ │ ├── dashboard.css │ │ │ ├── fonts.css │ │ │ ├── forms.css │ │ │ ├── login.css │ │ │ ├── responsive.css │ │ │ ├── responsive_rtl.css │ │ │ ├── rtl.css │ │ │ ├── vendor │ │ │ │ └── select2 │ │ │ │ │ ├── LICENSE-SELECT2.md │ │ │ │ │ ├── select2.css │ │ │ │ │ └── select2.min.css │ │ │ └── widgets.css │ │ ├── fonts │ │ │ ├── LICENSE.txt │ │ │ ├── README.txt │ │ │ ├── Roboto-Bold-webfont.woff │ │ │ ├── Roboto-Light-webfont.woff │ │ │ └── Roboto-Regular-webfont.woff │ │ ├── img │ │ │ ├── LICENSE │ │ │ ├── README.txt │ │ │ ├── calendar-icons.svg │ │ │ ├── gis │ │ │ │ ├── move_vertex_off.svg │ │ │ │ └── move_vertex_on.svg │ │ │ ├── icon-addlink.svg │ │ │ ├── icon-alert.svg │ │ │ ├── icon-calendar.svg │ │ │ ├── icon-changelink.svg │ │ │ ├── icon-clock.svg │ │ │ ├── icon-deletelink.svg │ │ │ ├── icon-no.svg │ │ │ ├── icon-unknown-alt.svg │ │ │ ├── icon-unknown.svg │ │ │ ├── icon-viewlink.svg │ │ │ ├── icon-yes.svg │ │ │ ├── inline-delete.svg │ │ │ ├── search.svg │ │ │ ├── selector-icons.svg │ │ │ ├── sorting-icons.svg │ │ │ ├── tooltag-add.svg │ │ │ └── tooltag-arrowright.svg │ │ └── js │ │ │ ├── SelectBox.js │ │ │ ├── SelectFilter2.js │ │ │ ├── actions.js │ │ │ ├── actions.min.js │ │ │ ├── admin │ │ │ ├── DateTimeShortcuts.js │ │ │ └── RelatedObjectLookups.js │ │ │ ├── autocomplete.js │ │ │ ├── calendar.js │ │ │ ├── cancel.js │ │ │ ├── change_form.js │ │ │ ├── collapse.js │ │ │ ├── collapse.min.js │ │ │ ├── core.js │ │ │ ├── inlines.js │ │ │ ├── inlines.min.js │ │ │ ├── jquery.init.js │ │ │ ├── popup_response.js │ │ │ ├── prepopulate.js │ │ │ ├── prepopulate.min.js │ │ │ ├── prepopulate_init.js │ │ │ ├── urlify.js │ │ │ └── vendor │ │ │ ├── jquery │ │ │ ├── LICENSE.txt │ │ │ ├── jquery.js │ │ │ └── jquery.min.js │ │ │ ├── select2 │ │ │ ├── LICENSE.md │ │ │ ├── i18n │ │ │ │ ├── af.js │ │ │ │ ├── ar.js │ │ │ │ ├── az.js │ │ │ │ ├── bg.js │ │ │ │ ├── bn.js │ │ │ │ ├── bs.js │ │ │ │ ├── ca.js │ │ │ │ ├── cs.js │ │ │ │ ├── da.js │ │ │ │ ├── de.js │ │ │ │ ├── dsb.js │ │ │ │ ├── el.js │ │ │ │ ├── en.js │ │ │ │ ├── es.js │ │ │ │ ├── et.js │ │ │ │ ├── eu.js │ │ │ │ ├── fa.js │ │ │ │ ├── fi.js │ │ │ │ ├── fr.js │ │ │ │ ├── gl.js │ │ │ │ ├── he.js │ │ │ │ ├── hi.js │ │ │ │ ├── hr.js │ │ │ │ ├── hsb.js │ │ │ │ ├── hu.js │ │ │ │ ├── hy.js │ │ │ │ ├── id.js │ │ │ │ ├── is.js │ │ │ │ ├── it.js │ │ │ │ ├── ja.js │ │ │ │ ├── ka.js │ │ │ │ ├── km.js │ │ │ │ ├── ko.js │ │ │ │ ├── lt.js │ │ │ │ ├── lv.js │ │ │ │ ├── mk.js │ │ │ │ ├── ms.js │ │ │ │ ├── nb.js │ │ │ │ ├── ne.js │ │ │ │ ├── nl.js │ │ │ │ ├── pl.js │ │ │ │ ├── ps.js │ │ │ │ ├── pt-BR.js │ │ │ │ ├── pt.js │ │ │ │ ├── ro.js │ │ │ │ ├── ru.js │ │ │ │ ├── sk.js │ │ │ │ ├── sl.js │ │ │ │ ├── sq.js │ │ │ │ ├── sr-Cyrl.js │ │ │ │ ├── sr.js │ │ │ │ ├── sv.js │ │ │ │ ├── th.js │ │ │ │ ├── tk.js │ │ │ │ ├── tr.js │ │ │ │ ├── uk.js │ │ │ │ ├── vi.js │ │ │ │ ├── zh-CN.js │ │ │ │ └── zh-TW.js │ │ │ ├── select2.full.js │ │ │ └── select2.full.min.js │ │ │ └── xregexp │ │ │ ├── LICENSE.txt │ │ │ ├── xregexp.js │ │ │ └── xregexp.min.js │ └── style.css └── templates │ └── base.html ├── 05_dstagram ├── .gitignore ├── Procfile ├── accounts │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── registration │ │ │ ├── login.html │ │ │ ├── logout.html │ │ │ ├── register.html │ │ │ └── register_done.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── config │ ├── __init__.py │ ├── asgi.py │ ├── s3media.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── media │ └── photos │ │ └── 2020 │ │ └── 05 │ │ ├── 16 │ │ ├── image_02_01.png │ │ └── 스크린샷_2016-05-26_오후_5.54.35.png │ │ └── 19 │ │ └── 스크린샷_2016-05-26_오후_5.54.35.png ├── photo │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── photo │ │ │ ├── delete.html │ │ │ ├── detail.html │ │ │ ├── list.html │ │ │ ├── update.html │ │ │ └── upload.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── requirements.txt ├── runtime.txt └── templates │ └── base.html ├── 06_onlineshop ├── cart │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── cart.py │ ├── context_processors.py │ ├── forms.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── cart │ │ │ └── detail.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── config │ ├── __init__.py │ ├── asgi.py │ ├── s3_media_upload.py │ ├── s3media.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── coupon │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── manage.py ├── order │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── iamport.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── order │ │ │ ├── admin │ │ │ ├── detail.html │ │ │ └── pdf.html │ │ │ ├── create.html │ │ │ └── created.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── products │ └── 2020 │ │ └── 06 │ │ └── 26 │ │ └── mbp13touch-space-select-202005_GEO_KR.jpg ├── requirements.txt ├── shop │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── shop │ │ │ ├── detail.html │ │ │ └── list.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── static │ ├── css │ │ └── pdf.css │ └── js │ │ └── checkout.js └── templates │ └── base.html ├── 08_booking ├── booking │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── templates │ │ └── rest_framework_swagger │ │ │ └── base.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── config │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py └── django_basic ├── config ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py ├── views.py └── wsgi.py ├── manage.py └── templates └── test.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | venv 3 | __pycache__ 4 | *.pyc 5 | *~ 6 | .idea 7 | *.sqlite3 8 | secret_keys.py 9 | -------------------------------------------------------------------------------- /04_bookmark/bookmark/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/04_bookmark/bookmark/__init__.py -------------------------------------------------------------------------------- /04_bookmark/bookmark/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | # 내가 만든 모델을 관리자 페이지에서 관리할 수 있도록 등록 5 | from .models import Bookmark 6 | 7 | admin.site.register(Bookmark) -------------------------------------------------------------------------------- /04_bookmark/bookmark/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BookmarkConfig(AppConfig): 5 | name = 'bookmark' 6 | -------------------------------------------------------------------------------- /04_bookmark/bookmark/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.5 on 2020-04-22 15:51 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='Bookmark', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('site_name', models.CharField(max_length=100)), 19 | ('url', models.URLField(verbose_name='Site URL')), 20 | ], 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /04_bookmark/bookmark/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/04_bookmark/bookmark/migrations/__init__.py -------------------------------------------------------------------------------- /04_bookmark/bookmark/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.urls import reverse 3 | # Create your models here. 4 | # 모델 : 데이터베이스를 SQL없이 다루려고 모델을 사용 5 | # 우리가 데이터를 객체화해서 다루겠다. 6 | # 모델 = 테이블 7 | # 모델의 필드 = 테이블의 컬럼 8 | # 인스턴스 = 테이블의 레코드 9 | # 필드의 값(인스턴스의 필드값) = 레코드의 컬럼 데이터값 10 | class Bookmark(models.Model): 11 | site_name = models.CharField(max_length=100) 12 | url = models.URLField('Site URL') 13 | # 필드의 종류가 결정하는 것 14 | # 1. 데이터베이스의 컬럼 종류 15 | # 2. 제약 사항 (몇글자까지) 16 | # 3. Form의 종류 17 | # 4. Form에서 제약 사항 18 | 19 | def __str__(self): 20 | return "이름 : "+self.site_name+", 주소 : "+self.url 21 | 22 | def get_absolute_url(self): 23 | return reverse('detail', args=[self.id]) 24 | 25 | # 모델을 만들었다 => 데이터베이스에 어떤 데이터들을 어떤 형태로 넣을지 결정! 26 | # makemigrations => 모델의 변경사항을 추적해서 기록 27 | # 마이그레이션(migrate) => 데이터베이스에 모델의 내용을 반영(테이블 생성) 28 | -------------------------------------------------------------------------------- /04_bookmark/bookmark/templates/bookmark/bookmark_confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}Confirm Delete{% endblock %} 3 | {% block content %} 4 |
5 | {%csrf_token%} 6 |
Do you want to delete Bookmark "{{object}}"?
7 | 8 |
9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /04_bookmark/bookmark/templates/bookmark/bookmark_create.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}Bookmark Add{% endblock %} 3 | {% block content %} 4 |
5 | {% csrf_token %} 6 | {{form.as_p}} 7 | 8 |
9 | {% endblock %} -------------------------------------------------------------------------------- /04_bookmark/bookmark/templates/bookmark/bookmark_detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}Detail{% endblock %} 3 | {% block content %} 4 | {{object.site_name}}
5 | {{object.url}} 6 | {% endblock %} -------------------------------------------------------------------------------- /04_bookmark/bookmark/templates/bookmark/bookmark_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}Bookmark List{% endblock %} 3 | {% block content %} 4 |
5 | Add Bookmark 6 |
7 |

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% for bookmark in object_list %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {% endfor %} 28 | 29 |
#SiteURLModifyDelete
{{forloop.counter}}{{bookmark.site_name}}{{bookmark.url}}ModifyDelete
30 | {% endblock %} -------------------------------------------------------------------------------- /04_bookmark/bookmark/templates/bookmark/bookmark_update.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}Bookmark Add{% endblock %} 3 | {% block content %} 4 |
5 | {% csrf_token %} 6 | {{form.as_p}} 7 | 8 |
9 | {% endblock %} -------------------------------------------------------------------------------- /04_bookmark/bookmark/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /04_bookmark/bookmark/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from .views import * 3 | 4 | urlpatterns = [ 5 | # http://127.0.0.1/bookmark/ 6 | # 7 | path("", BookmarkListView.as_view(), name='list'), 8 | path("add/", BookmarkCreateView.as_view(), name='add'), 9 | path("detail//", BookmarkDetailView.as_view(), name='detail'), 10 | path("update//", BookmarkUpdateView.as_view(), name='update'), 11 | path("delete//", BookmarkDeleteView.as_view(), name='delete'), 12 | ] -------------------------------------------------------------------------------- /04_bookmark/bookmark/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | # CRUD : Create, Read, Update, Delete 5 | # List 6 | 7 | # 클래스형 뷰, 함수형 뷰 8 | # 웹 페이지에 접속한다. -> 페이지를 본다. 9 | # URL을 입력 -> 웹 서버가 뷰를 찾아서 동작시킨다. -> 응답 10 | from django.views.generic.list import ListView 11 | from django.views.generic.edit import CreateView, UpdateView, DeleteView 12 | from django.views.generic.detail import DetailView 13 | 14 | from django.urls import reverse_lazy 15 | from .models import Bookmark 16 | 17 | class BookmarkListView(ListView): 18 | model = Bookmark 19 | 20 | class BookmarkCreateView(CreateView): 21 | model = Bookmark 22 | fields = ['site_name','url'] 23 | success_url = reverse_lazy('list') 24 | template_name_suffix = '_create' 25 | 26 | class BookmarkDetailView(DetailView): 27 | model = Bookmark 28 | 29 | class BookmarkUpdateView(UpdateView): 30 | model = Bookmark 31 | fields = ['site_name','url'] 32 | template_name_suffix = '_update' 33 | 34 | class BookmarkDeleteView(DeleteView): 35 | model = Bookmark 36 | success_url = reverse_lazy('list') 37 | -------------------------------------------------------------------------------- /04_bookmark/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/04_bookmark/config/__init__.py -------------------------------------------------------------------------------- /04_bookmark/config/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for config project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /04_bookmark/config/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for config project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.0.5. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.0/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'ooms#x80312rr_1u1e05bg-$-77aj(uyie8nuxme$4a#)fuork' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'bookmark', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'config.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [os.path.join(BASE_DIR,'templates')], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'config.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/3.0/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/3.0/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'UTC' 110 | 111 | USE_I18N = True 112 | 113 | USE_L10N = True 114 | 115 | USE_TZ = True 116 | 117 | 118 | # Static files (CSS, JavaScript, Images) 119 | # https://docs.djangoproject.com/en/3.0/howto/static-files/ 120 | 121 | STATIC_URL = '/static/' 122 | 123 | STATIC_ROOT = os.path.join(BASE_DIR, 'static_files') 124 | STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] -------------------------------------------------------------------------------- /04_bookmark/config/urls.py: -------------------------------------------------------------------------------- 1 | """config URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | urlpatterns = [ 20 | # 1차 -> 2차 -> 3차 21 | # http://127.0.0.1/bookmark/? 22 | # http://127.0.0.1/중앙창구/외과 23 | # http://127.0.0.1/중앙창구/내과 24 | path('bookmark/', include('bookmark.urls')), 25 | # http://127.0.0.1/admin/ 26 | path('admin/', admin.site.urls), 27 | 28 | ] 29 | -------------------------------------------------------------------------------- /04_bookmark/config/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for config project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /04_bookmark/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /04_bookmark/static/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | width:100%; 3 | } -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/css/dashboard.css: -------------------------------------------------------------------------------- 1 | /* DASHBOARD */ 2 | 3 | .dashboard .module table th { 4 | width: 100%; 5 | } 6 | 7 | .dashboard .module table td { 8 | white-space: nowrap; 9 | } 10 | 11 | .dashboard .module table td a { 12 | display: block; 13 | padding-right: .6em; 14 | } 15 | 16 | /* RECENT ACTIONS MODULE */ 17 | 18 | .module ul.actionlist { 19 | margin-left: 0; 20 | } 21 | 22 | ul.actionlist li { 23 | list-style-type: none; 24 | overflow: hidden; 25 | text-overflow: ellipsis; 26 | -o-text-overflow: ellipsis; 27 | } 28 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/css/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Roboto'; 3 | src: url('../fonts/Roboto-Bold-webfont.woff'); 4 | font-weight: 700; 5 | font-style: normal; 6 | } 7 | 8 | @font-face { 9 | font-family: 'Roboto'; 10 | src: url('../fonts/Roboto-Regular-webfont.woff'); 11 | font-weight: 400; 12 | font-style: normal; 13 | } 14 | 15 | @font-face { 16 | font-family: 'Roboto'; 17 | src: url('../fonts/Roboto-Light-webfont.woff'); 18 | font-weight: 300; 19 | font-style: normal; 20 | } 21 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/css/login.css: -------------------------------------------------------------------------------- 1 | /* LOGIN FORM */ 2 | 3 | body.login { 4 | background: #f8f8f8; 5 | } 6 | 7 | .login #header { 8 | height: auto; 9 | padding: 15px 16px; 10 | justify-content: center; 11 | } 12 | 13 | .login #header h1 { 14 | font-size: 18px; 15 | } 16 | 17 | .login #header h1 a { 18 | color: #fff; 19 | } 20 | 21 | .login #content { 22 | padding: 20px 20px 0; 23 | } 24 | 25 | .login #container { 26 | background: #fff; 27 | border: 1px solid #eaeaea; 28 | border-radius: 4px; 29 | overflow: hidden; 30 | width: 28em; 31 | min-width: 300px; 32 | margin: 100px auto; 33 | } 34 | 35 | .login #content-main { 36 | width: 100%; 37 | } 38 | 39 | .login .form-row { 40 | padding: 4px 0; 41 | float: left; 42 | width: 100%; 43 | border-bottom: none; 44 | } 45 | 46 | .login .form-row label { 47 | padding-right: 0.5em; 48 | line-height: 2em; 49 | font-size: 1em; 50 | clear: both; 51 | color: #333; 52 | } 53 | 54 | .login .form-row #id_username, .login .form-row #id_password { 55 | clear: both; 56 | padding: 8px; 57 | width: 100%; 58 | -webkit-box-sizing: border-box; 59 | -moz-box-sizing: border-box; 60 | box-sizing: border-box; 61 | } 62 | 63 | .login span.help { 64 | font-size: 10px; 65 | display: block; 66 | } 67 | 68 | .login .submit-row { 69 | clear: both; 70 | padding: 1em 0 0 9.4em; 71 | margin: 0; 72 | border: none; 73 | background: none; 74 | text-align: left; 75 | } 76 | 77 | .login .password-reset-link { 78 | text-align: center; 79 | } 80 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/css/responsive_rtl.css: -------------------------------------------------------------------------------- 1 | /* TABLETS */ 2 | 3 | @media (max-width: 1024px) { 4 | [dir="rtl"] .colMS { 5 | margin-right: 0; 6 | } 7 | 8 | [dir="rtl"] #user-tools { 9 | text-align: right; 10 | } 11 | 12 | [dir="rtl"] #changelist .actions label { 13 | padding-left: 10px; 14 | padding-right: 0; 15 | } 16 | 17 | [dir="rtl"] #changelist .actions select { 18 | margin-left: 0; 19 | margin-right: 15px; 20 | } 21 | 22 | [dir="rtl"] .change-list .filtered .results, 23 | [dir="rtl"] .change-list .filtered .paginator, 24 | [dir="rtl"] .filtered #toolbar, 25 | [dir="rtl"] .filtered div.xfull, 26 | [dir="rtl"] .filtered .actions { 27 | margin-right: 0; 28 | margin-left: 230px; 29 | } 30 | 31 | [dir="rtl"] .inline-group ul.tools a.add, 32 | [dir="rtl"] .inline-group div.add-row a, 33 | [dir="rtl"] .inline-group .tabular tr.add-row td a { 34 | padding: 8px 26px 8px 10px; 35 | background-position: calc(100% - 8px) 9px; 36 | } 37 | 38 | [dir="rtl"] .related-widget-wrapper-link + .selector { 39 | margin-right: 0; 40 | margin-left: 15px; 41 | } 42 | 43 | [dir="rtl"] .selector .selector-filter label { 44 | margin-right: 0; 45 | margin-left: 8px; 46 | } 47 | 48 | [dir="rtl"] .object-tools li { 49 | float: right; 50 | } 51 | 52 | [dir="rtl"] .object-tools li + li { 53 | margin-left: 0; 54 | margin-right: 15px; 55 | } 56 | 57 | [dir="rtl"] .dashboard .module table td a { 58 | padding-left: 0; 59 | padding-right: 16px; 60 | } 61 | } 62 | 63 | /* MOBILE */ 64 | 65 | @media (max-width: 767px) { 66 | [dir="rtl"] .change-list .filtered .results, 67 | [dir="rtl"] .change-list .filtered .paginator, 68 | [dir="rtl"] .filtered #toolbar, 69 | [dir="rtl"] .filtered div.xfull, 70 | [dir="rtl"] .filtered .actions { 71 | margin-left: 0; 72 | } 73 | 74 | [dir="rtl"] .aligned .add-another, 75 | [dir="rtl"] .aligned .related-lookup, 76 | [dir="rtl"] .aligned .datetimeshortcuts { 77 | margin-left: 0; 78 | margin-right: 15px; 79 | } 80 | 81 | [dir="rtl"] .aligned ul { 82 | margin-right: 0; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/css/vendor/select2/LICENSE-SELECT2.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/fonts/README.txt: -------------------------------------------------------------------------------- 1 | Roboto webfont source: https://www.google.com/fonts/specimen/Roboto 2 | WOFF files extracted using https://github.com/majodev/google-webfonts-helper 3 | Weights used in this project: Light (300), Regular (400), Bold (700) 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/fonts/Roboto-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/04_bookmark/static_files/admin/fonts/Roboto-Bold-webfont.woff -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/fonts/Roboto-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/04_bookmark/static_files/admin/fonts/Roboto-Light-webfont.woff -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/fonts/Roboto-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/04_bookmark/static_files/admin/fonts/Roboto-Regular-webfont.woff -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Code Charm Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/README.txt: -------------------------------------------------------------------------------- 1 | All icons are taken from Font Awesome (http://fontawesome.io/) project. 2 | The Font Awesome font is licensed under the SIL OFL 1.1: 3 | - https://scripts.sil.org/OFL 4 | 5 | SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG 6 | Font-Awesome-SVG-PNG is licensed under the MIT license (see file license 7 | in current folder). 8 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/calendar-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/gis/move_vertex_off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/gis/move_vertex_on.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-addlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-calendar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-changelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-clock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-deletelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-unknown-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-unknown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-viewlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/icon-yes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/inline-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/selector-icons.svg: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/sorting-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/tooltag-add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/img/tooltag-arrowright.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/actions.min.js: -------------------------------------------------------------------------------- 1 | (function(a){var f;a.fn.actions=function(e){var b=a.extend({},a.fn.actions.defaults,e),g=a(this),k=!1,l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()},m=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},n=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},p=function(){n(); 2 | a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)},q=function(c){c?l():n();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length,d=a(".action-counter").data("actionsIcnt");a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:d},!0));a(b.allToggle).prop("checked",function(){if(c===g.length){var a=!0;l()}else a=!1,p();return a})};a(b.counterContainer).show(); 3 | a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass);h();1===a(b.acrossInput).val()&&m()});a(b.allToggle).show().on("click",function(){q(a(this).prop("checked"));h()});a("a",b.acrossQuestions).on("click",function(c){c.preventDefault();a(b.acrossInput).val(1);m()});a("a",b.acrossClears).on("click",function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);p();q(0);h()});f=null;a(g).on("click",function(c){c||(c=window.event);var d=c.target?c.target: 4 | c.srcElement;if(f&&a.data(f)!==a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(g).each(function(){if(a.data(this)===a.data(f)||a.data(this)===a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").on("change","td:gt(0) :input",function(){k=!0}); 5 | a('form#changelist-form button[name="index"]').on("click",function(a){if(k)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').on("click",function(c){var d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return k?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")): 6 | confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"};a(document).ready(function(){var e= 7 | a("tr input.action-select");0 0) { 26 | values.push(field.val()); 27 | } 28 | }); 29 | prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode)); 30 | }; 31 | 32 | prepopulatedField.data('_changed', false); 33 | prepopulatedField.on('change', function() { 34 | prepopulatedField.data('_changed', true); 35 | }); 36 | 37 | if (!prepopulatedField.val()) { 38 | $(dependencies.join(',')).on('keyup change focus', populate); 39 | } 40 | }); 41 | }; 42 | })(django.jQuery); 43 | -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/prepopulate.min.js: -------------------------------------------------------------------------------- 1 | (function(b){b.fn.prepopulate=function(d,f,g){return this.each(function(){var a=b(this),h=function(){if(!a.data("_changed")){var e=[];b.each(d,function(a,c){c=b(c);01&&(n+="a"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Моля въведете още "+t+" символ";return t>1&&(n+="a"),n},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(e){var t="Можете да направите до "+e.maximum+" ";return e.maximum>1?t+="избора":t+="избор",t},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/bn.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="অনুগ্রহ করে "+t+" টি অক্ষর মুছে দিন।";return t!=1&&(n="অনুগ্রহ করে "+t+" টি অক্ষর মুছে দিন।"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=t+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।";return n},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(e){var t=e.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return e.maximum!=1&&(t=e.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),t},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/bs.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/bs",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Obrišite "+n+" simbol";return r+=e(n,"","a","a"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Ukucajte bar još "+n+" simbol";return r+=e(n,"","a","a"),r},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(t){var n="Možete izabrati samo "+t.maximum+" stavk";return n+=e(t.maximum,"u","e","i"),n},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Uklonite sve stavke"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/ca.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Si us plau, elimina "+t+" car";return t==1?n+="àcter":n+="àcters",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Si us plau, introdueix "+t+" car";return t==1?n+="àcter":n+="àcters",n},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var t="Només es pot seleccionar "+e.maximum+" element";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/cs.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/cs",[],function(){function e(e,t){switch(e){case 2:return t?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?"Prosím, zadejte o jeden znak méně.":n<=4?"Prosím, zadejte o "+e(n,!0)+" znaky méně.":"Prosím, zadejte o "+n+" znaků méně."},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?"Prosím, zadejte ještě jeden znak.":n<=4?"Prosím, zadejte ještě další "+e(n,!0)+" znaky.":"Prosím, zadejte ještě dalších "+n+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(t){var n=t.maximum;return n==1?"Můžete zvolit jen jednu položku.":n<=4?"Můžete zvolit maximálně "+e(n,!1)+" položky.":"Můžete zvolit maximálně "+n+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"},removeAllItems:function(){return"Odstraňte všechny položky"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/da.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Angiv venligst "+t+" tegn mindre"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Angiv venligst "+t+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var t="Du kan kun vælge "+e.maximum+" emne";return e.maximum!=1&&(t+="r"),t},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/de.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Bitte "+t+" Zeichen weniger eingeben"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Bitte "+t+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var t="Sie können nur "+e.maximum+" Eintr";return e.maximum===1?t+="ag":t+="äge",t+=" auswählen",t},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Gegenstände"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/dsb.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/dsb",[],function(){var e=["znamuško","znamušce","znamuška","znamuškow"],t=["zapisk","zapiska","zapiski","zapiskow"],n=function(t,n){if(t===1)return n[0];if(t===2)return n[1];if(t>2&&t<=4)return n[2];if(t>=5)return n[3]};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(t){var r=t.input.length-t.maximum;return"Pšosym lašuj "+r+" "+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return"Pšosym zapódaj nanejmjenjej "+r+" "+n(r,e)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(e){return"Móžoš jano "+e.maximum+" "+n(e.maximum,t)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"},removeAllItems:function(){return"Remove all items"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/el.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Παρακαλώ διαγράψτε "+t+" χαρακτήρ";return t==1&&(n+="α"),t!=1&&(n+="ες"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Παρακαλώ συμπληρώστε "+t+" ή περισσότερους χαρακτήρες";return n},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(e){var t="Μπορείτε να επιλέξετε μόνο "+e.maximum+" επιλογ";return e.maximum==1&&(t+="ή"),e.maximum!=1&&(t+="ές"),t},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/en.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Please delete "+t+" character";return t!=1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Please enter "+t+" or more characters";return n},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var t="You can only select "+e.maximum+" item";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/es.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"No se pudieron cargar los resultados"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor, elimine "+t+" car";return t==1?n+="ácter":n+="acteres",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Por favor, introduzca "+t+" car";return t==1?n+="ácter":n+="acteres",n},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var t="Sólo puede seleccionar "+e.maximum+" elemento";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Eliminar todos los elementos"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/et.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Sisesta "+t+" täht";return t!=1&&(n+="e"),n+=" vähem",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Sisesta "+t+" täht";return t!=1&&(n+="e"),n+=" rohkem",n},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var t="Saad vaid "+e.maximum+" tulemus";return e.maximum==1?t+="e":t+="t",t+=" valida",t},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"},removeAllItems:function(){return"Eemalda kõik esemed"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/eu.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return t==1?n+="karaktere bat":n+=t+" karaktere",n+=" gutxiago",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return t==1?n+="karaktere bat":n+=t+" karaktere",n+=" gehiago",n},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return e.maximum===1?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"},removeAllItems:function(){return"Kendu elementu guztiak"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/fa.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="لطفاً "+t+" کاراکتر را حذف نمایید";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="لطفاً تعداد "+t+" کاراکتر یا بیشتر وارد نمایید";return n},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(e){var t="شما تنها می‌توانید "+e.maximum+" آیتم را انتخاب نمایید";return t},noResults:function(){return"هیچ نتیجه‌ای یافت نشد"},searching:function(){return"در حال جستجو..."},removeAllItems:function(){return"همه موارد را حذف کنید"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/fi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Ole hyvä ja anna "+t+" merkkiä vähemmän"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Ole hyvä ja anna "+t+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(e){return"Voit valita ainoastaan "+e.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"},removeAllItems:function(){return"Poista kaikki kohteet"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/fr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Supprimez "+t+" caractère"+(t>1?"s":"")},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Saisissez au moins "+t+" caractère"+(t>1?"s":"")},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){return"Vous pouvez seulement sélectionner "+e.maximum+" élément"+(e.maximum>1?"s":"")},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"},removeAllItems:function(){return"Supprimer tous les articles"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/gl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/gl",[],function(){return{errorLoading:function(){return"Non foi posíbel cargar os resultados."},inputTooLong:function(e){var t=e.input.length-e.maximum;return t===1?"Elimine un carácter":"Elimine "+t+" caracteres"},inputTooShort:function(e){var t=e.minimum-e.input.length;return t===1?"Engada un carácter":"Engada "+t+" caracteres"},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){return e.maximum===1?"Só pode seleccionar un elemento":"Só pode seleccionar "+e.maximum+" elementos"},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Elimina todos os elementos"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/he.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="נא למחוק ";return t===1?n+="תו אחד":n+=t+" תווים",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="נא להכניס ";return t===1?n+="תו אחד":n+=t+" תווים",n+=" או יותר",n},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(e){var t="באפשרותך לבחור עד ";return e.maximum===1?t+="פריט אחד":t+=e.maximum+" פריטים",t},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"},removeAllItems:function(){return"הסר את כל הפריטים"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/hi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" अक्षर को हटा दें";return t>1&&(n=t+" अक्षरों को हटा दें "),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="कृपया "+t+" या अधिक अक्षर दर्ज करें";return n},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(e){var t="आप केवल "+e.maximum+" आइटम का चयन कर सकते हैं";return t},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."},removeAllItems:function(){return"सभी वस्तुओं को हटा दें"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/hr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hr",[],function(){function e(e){var t=" "+e+" znak";return e%10<5&&e%10>0&&(e%100<5||e%100>19)?e%10>1&&(t+="a"):t+="ova",t}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(t){var n=t.input.length-t.maximum;return"Unesite "+e(n)},inputTooShort:function(t){var n=t.minimum-t.input.length;return"Unesite još "+e(n)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(e){return"Maksimalan broj odabranih stavki je "+e.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Ukloni sve stavke"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/hsb.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hsb",[],function(){var e=["znamješko","znamješce","znamješka","znamješkow"],t=["zapisk","zapiskaj","zapiski","zapiskow"],n=function(t,n){if(t===1)return n[0];if(t===2)return n[1];if(t>2&&t<=4)return n[2];if(t>=5)return n[3]};return{errorLoading:function(){return"Wuslědki njedachu so začitać."},inputTooLong:function(t){var r=t.input.length-t.maximum;return"Prošu zhašej "+r+" "+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return"Prošu zapodaj znajmjeńša "+r+" "+n(r,e)},loadingMore:function(){return"Dalše wuslědki so začitaja…"},maximumSelected:function(e){return"Móžeš jenož "+e.maximum+" "+n(e.maximum,t)+"wubrać"},noResults:function(){return"Žane wuslědki namakane"},searching:function(){return"Pyta so…"},removeAllItems:function(){return"Remove all items"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/hu.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Túl hosszú. "+t+" karakterrel több, mint kellene."},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Túl rövid. Még "+t+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"},removeAllItems:function(){return"Távolítson el minden elemet"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/hy.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Խնդրում ենք հեռացնել "+t+" նշան";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Խնդրում ենք մուտքագրել "+t+" կամ ավել նշաններ";return n},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(e){var t="Դուք կարող եք ընտրել առավելագույնը "+e.maximum+" կետ";return t},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"},removeAllItems:function(){return"Հեռացնել բոլոր տարրերը"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/id.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Hapuskan "+t+" huruf"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Masukkan "+t+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(e){return"Anda hanya dapat memilih "+e.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Hapus semua item"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/is.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/is",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vinsamlegast styttið texta um "+t+" staf";return t<=1?n:n+"i"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vinsamlegast skrifið "+t+" staf";return t>1&&(n+="i"),n+=" í viðbót",n},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(e){return"Þú getur aðeins valið "+e.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"},removeAllItems:function(){return"Fjarlægðu öll atriði"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/it.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Per favore cancella "+t+" caratter";return t!==1?n+="i":n+="e",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Per favore inserisci "+t+" o più caratteri";return n},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var t="Puoi selezionare solo "+e.maximum+" element";return e.maximum!==1?t+="i":t+="o",t},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"},removeAllItems:function(){return"Rimuovi tutti gli oggetti"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/ja.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" 文字を削除してください";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="少なくとも "+t+" 文字を入力してください";return n},loadingMore:function(){return"読み込み中…"},maximumSelected:function(e){var t=e.maximum+" 件しか選択できません";return t},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"},removeAllItems:function(){return"すべてのアイテムを削除"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/ka.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ka",[],function(){return{errorLoading:function(){return"მონაცემების ჩატვირთვა შეუძლებელია."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="გთხოვთ აკრიფეთ "+t+" სიმბოლოთი ნაკლები";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="გთხოვთ აკრიფეთ "+t+" სიმბოლო ან მეტი";return n},loadingMore:function(){return"მონაცემების ჩატვირთვა…"},maximumSelected:function(e){var t="თქვენ შეგიძლიათ აირჩიოთ არაუმეტეს "+e.maximum+" ელემენტი";return t},noResults:function(){return"რეზულტატი არ მოიძებნა"},searching:function(){return"ძიება…"},removeAllItems:function(){return"ამოიღე ყველა ელემენტი"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/km.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="សូមលុបចេញ "+t+" អក្សរ";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="សូមបញ្ចូល"+t+" អក្សរ រឺ ច្រើនជាងនេះ";return n},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(e){var t="អ្នកអាចជ្រើសរើសបានតែ "+e.maximum+" ជម្រើសប៉ុណ្ណោះ";return t},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."},removeAllItems:function(){return"លុបធាតុទាំងអស់"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/ko.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="너무 깁니다. "+t+" 글자 지워주세요.";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="너무 짧습니다. "+t+" 글자 더 입력해주세요.";return n},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(e){var t="최대 "+e.maximum+"개까지만 선택 가능합니다.";return t},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"},removeAllItems:function(){return"모든 항목 삭제"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/lt.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/lt",[],function(){function e(e,t,n,r){return e%10===1&&(e%100<11||e%100>19)?t:e%10>=2&&e%10<=9&&(e%100<11||e%100>19)?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r="Pašalinkite "+n+" simbol";return r+=e(n,"į","ius","ių"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Įrašykite dar "+n+" simbol";return r+=e(n,"į","ius","ių"),r},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(t){var n="Jūs galite pasirinkti tik "+t.maximum+" element";return n+=e(t.maximum,"ą","us","ų"),n},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"},removeAllItems:function(){return"Pašalinti visus elementus"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/lv.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/lv",[],function(){function e(e,t,n,r){return e===11?t:e%10===1?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r="Lūdzu ievadiet par "+n;return r+=" simbol"+e(n,"iem","u","iem"),r+" mazāk"},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Lūdzu ievadiet vēl "+n;return r+=" simbol"+e(n,"us","u","us"),r},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(t){var n="Jūs varat izvēlēties ne vairāk kā "+t.maximum;return n+=" element"+e(t.maximum,"us","u","us"),n},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"},removeAllItems:function(){return"Noņemt visus vienumus"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/mk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/mk",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Ве молиме внесете "+e.maximum+" помалку карактер";return e.maximum!==1&&(n+="и"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Ве молиме внесете уште "+e.maximum+" карактер";return e.maximum!==1&&(n+="и"),n},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(e){var t="Можете да изберете само "+e.maximum+" ставк";return e.maximum===1?t+="а":t+="и",t},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"},removeAllItems:function(){return"Отстрани ги сите предмети"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/ms.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Sila hapuskan "+t+" aksara"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Sila masukkan "+t+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(e){return"Anda hanya boleh memilih "+e.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Keluarkan semua item"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/nb.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Vennligst fjern "+t+" tegn"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Vennligst skriv inn "+t+" tegn til"},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"},removeAllItems:function(){return"Fjern alle elementer"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/ne.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ne",[],function(){return{errorLoading:function(){return"नतिजाहरु देखाउन सकिएन।"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="कृपया "+t+" अक्षर मेटाउनुहोस्।";return t!=1&&(n+="कृपया "+t+" अक्षरहरु मेटाउनुहोस्।"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="कृपया बाँकी रहेका "+t+" वा अरु धेरै अक्षरहरु भर्नुहोस्।";return n},loadingMore:function(){return"अरु नतिजाहरु भरिँदैछन् …"},maximumSelected:function(e){var t="तँपाई "+e.maximum+" वस्तु मात्र छान्न पाउँनुहुन्छ।";return e.maximum!=1&&(t="तँपाई "+e.maximum+" वस्तुहरु मात्र छान्न पाउँनुहुन्छ।"),t},noResults:function(){return"कुनै पनि नतिजा भेटिएन।"},searching:function(){return"खोजि हुँदैछ…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/nl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Gelieve "+t+" karakters te verwijderen";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Gelieve "+t+" of meer karakters in te voeren";return n},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var t=e.maximum==1?"kan":"kunnen",n="Er "+t+" maar "+e.maximum+" item";return e.maximum!=1&&(n+="s"),n+=" worden geselecteerd",n},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"},removeAllItems:function(){return"Verwijder alle items"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/pl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pl",[],function(){var e=["znak","znaki","znaków"],t=["element","elementy","elementów"],n=function(t,n){if(t===1)return n[0];if(t>1&&t<=4)return n[1];if(t>=5)return n[2]};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(t){var r=t.input.length-t.maximum;return"Usuń "+r+" "+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return"Podaj przynajmniej "+r+" "+n(r,e)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(e){return"Możesz zaznaczyć tylko "+e.maximum+" "+n(e.maximum,t)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"},removeAllItems:function(){return"Usuń wszystkie przedmioty"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/ps.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="د مهربانۍ لمخي "+t+" توری ړنګ کړئ";return t!=1&&(n=n.replace("توری","توري")),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="لږ تر لږه "+t+" يا ډېر توري وليکئ";return n},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(e){var t="تاسو يوازي "+e.maximum+" قلم په نښه کولای سی";return e.maximum!=1&&(t=t.replace("قلم","قلمونه")),t},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."},removeAllItems:function(){return"ټول توکي لرې کړئ"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/pt-BR.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Apague "+t+" caracter";return t!=1&&(n+="es"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Digite "+t+" ou mais caracteres";return n},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var t="Você só pode selecionar "+e.maximum+" ite";return e.maximum==1?t+="m":t+="ns",t},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Remover todos os itens"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/pt.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor apague "+t+" ";return n+=t!=1?"caracteres":"caractere",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Introduza "+t+" ou mais caracteres";return n},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var t="Apenas pode seleccionar "+e.maximum+" ";return t+=e.maximum!=1?"itens":"item",t},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"},removeAllItems:function(){return"Remover todos os itens"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/ro.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return t!==1&&(n+="e"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vă rugăm să introduceți "+t+" sau mai multe caractere";return n},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",e.maximum!==1&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"},removeAllItems:function(){return"Eliminați toate elementele"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/ru.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ru",[],function(){function e(e,t,n,r){return e%10<5&&e%10>0&&e%100<5||e%100>20?e%10>1?n:t:r}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Пожалуйста, введите на "+n+" символ";return r+=e(n,"","a","ов"),r+=" меньше",r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Пожалуйста, введите ещё хотя бы "+n+" символ";return r+=e(n,"","a","ов"),r},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(t){var n="Вы можете выбрать не более "+t.maximum+" элемент";return n+=e(t.maximum,"","a","ов"),n},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"},removeAllItems:function(){return"Удалить все элементы"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/sk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{errorLoading:function(){return"Výsledky sa nepodarilo načítať."},inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?"Prosím, zadajte o jeden znak menej":n>=2&&n<=4?"Prosím, zadajte o "+e[n](!0)+" znaky menej":"Prosím, zadajte o "+n+" znakov menej"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?"Prosím, zadajte ešte jeden znak":n<=4?"Prosím, zadajte ešte ďalšie "+e[n](!0)+" znaky":"Prosím, zadajte ešte ďalších "+n+" znakov"},loadingMore:function(){return"Načítanie ďalších výsledkov…"},maximumSelected:function(t){return t.maximum==1?"Môžete zvoliť len jednu položku":t.maximum>=2&&t.maximum<=4?"Môžete zvoliť najviac "+e[t.maximum](!1)+" položky":"Môžete zvoliť najviac "+t.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"},removeAllItems:function(){return"Odstráňte všetky položky"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/sl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sl",[],function(){return{errorLoading:function(){return"Zadetkov iskanja ni bilo mogoče naložiti."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Prosim zbrišite "+t+" znak";return t==2?n+="a":t!=1&&(n+="e"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Prosim vpišite še "+t+" znak";return t==2?n+="a":t!=1&&(n+="e"),n},loadingMore:function(){return"Nalagam več zadetkov…"},maximumSelected:function(e){var t="Označite lahko največ "+e.maximum+" predmet";return e.maximum==2?t+="a":e.maximum!=1&&(t+="e"),t},noResults:function(){return"Ni zadetkov."},searching:function(){return"Iščem…"},removeAllItems:function(){return"Odstranite vse elemente"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/sq.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sq",[],function(){return{errorLoading:function(){return"Rezultatet nuk mund të ngarkoheshin."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Të lutem fshi "+t+" karakter";return t!=1&&(n+="e"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Të lutem shkruaj "+t+" ose më shumë karaktere";return n},loadingMore:function(){return"Duke ngarkuar më shumë rezultate…"},maximumSelected:function(e){var t="Mund të zgjedhësh vetëm "+e.maximum+" element";return e.maximum!=1&&(t+="e"),t},noResults:function(){return"Nuk u gjet asnjë rezultat"},searching:function(){return"Duke kërkuar…"},removeAllItems:function(){return"Hiq të gjitha sendet"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/sr-Cyrl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sr-Cyrl",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Обришите "+n+" симбол";return r+=e(n,"","а","а"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Укуцајте бар још "+n+" симбол";return r+=e(n,"","а","а"),r},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(t){var n="Можете изабрати само "+t.maximum+" ставк";return n+=e(t.maximum,"у","е","и"),n},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"},removeAllItems:function(){return"Уклоните све ставке"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/sr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sr",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Obrišite "+n+" simbol";return r+=e(n,"","a","a"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Ukucajte bar još "+n+" simbol";return r+=e(n,"","a","a"),r},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(t){var n="Možete izabrati samo "+t.maximum+" stavk";return n+=e(t.maximum,"u","e","i"),n},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Уклоните све ставке"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/sv.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vänligen sudda ut "+t+" tecken";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vänligen skriv in "+t+" eller fler tecken";return n},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(e){var t="Du kan max välja "+e.maximum+" element";return t},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"},removeAllItems:function(){return"Ta bort alla objekt"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/th.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/th",[],function(){return{errorLoading:function(){return"ไม่สามารถค้นข้อมูลได้"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="โปรดลบออก "+t+" ตัวอักษร";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="โปรดพิมพ์เพิ่มอีก "+t+" ตัวอักษร";return n},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(e){var t="คุณสามารถเลือกได้ไม่เกิน "+e.maximum+" รายการ";return t},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"},removeAllItems:function(){return"ลบรายการทั้งหมด"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/tk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/tk",[],function(){return{errorLoading:function(){return"Netije ýüklenmedi."},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" harp bozuň.";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Ýene-de iň az "+t+" harp ýazyň.";return n},loadingMore:function(){return"Köpräk netije görkezilýär…"},maximumSelected:function(e){var t="Diňe "+e.maximum+" sanysyny saýlaň.";return t},noResults:function(){return"Netije tapylmady."},searching:function(){return"Gözlenýär…"},removeAllItems:function(){return"Remove all items"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/tr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/tr",[],function(){return{errorLoading:function(){return"Sonuç yüklenemedi"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" karakter daha girmelisiniz";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="En az "+t+" karakter daha girmelisiniz";return n},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(e){var t="Sadece "+e.maximum+" seçim yapabilirsiniz";return t},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"},removeAllItems:function(){return"Tüm öğeleri kaldır"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/uk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/uk",[],function(){function e(e,t,n,r){return e%100>10&&e%100<15?r:e%10===1?t:e%10>1&&e%10<5?n:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(t){var n=t.input.length-t.maximum;return"Будь ласка, видаліть "+n+" "+e(t.maximum,"літеру","літери","літер")},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Будь ласка, введіть "+t+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(t){return"Ви можете вибрати лише "+t.maximum+" "+e(t.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"},removeAllItems:function(){return"Видалити всі елементи"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/vi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/vi",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vui lòng xóa bớt "+t+" ký tự";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vui lòng nhập thêm từ "+t+" ký tự trở lên";return n},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(e){var t="Chỉ có thể chọn được "+e.maximum+" lựa chọn";return t},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"},removeAllItems:function(){return"Xóa tất cả các mục"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/zh-CN.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="请删除"+t+"个字符";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="请再输入至少"+t+"个字符";return n},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(e){var t="最多只能选择"+e.maximum+"个项目";return t},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"},removeAllItems:function(){return"删除所有项目"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/select2/i18n/zh-TW.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="請刪掉"+t+"個字元";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="請再輸入"+t+"個字元";return n},loadingMore:function(){return"載入中…"},maximumSelected:function(e){var t="你只能選擇最多"+e.maximum+"項";return t},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"},removeAllItems:function(){return"刪除所有項目"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /04_bookmark/static_files/admin/js/vendor/xregexp/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2007-2012 Steven Levithan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /04_bookmark/static_files/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | width:100%; 3 | } -------------------------------------------------------------------------------- /04_bookmark/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% block title %}{% endblock %} 6 | 7 | {% load static %} 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 28 |

29 |
30 |
31 | {% block content %} 32 | 33 | {% endblock %} 34 | 35 |
36 |
37 |
38 | 39 | -------------------------------------------------------------------------------- /05_dstagram/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *~ 3 | /venv 4 | __pycache__ 5 | db.sqlite3 6 | .DS_Store 7 | ._secret_keys.py 8 | **/secret_keys.py 9 | **/._secret_keys.py -------------------------------------------------------------------------------- /05_dstagram/Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn config.wsgi --log-file - -------------------------------------------------------------------------------- /05_dstagram/accounts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/05_dstagram/accounts/__init__.py -------------------------------------------------------------------------------- /05_dstagram/accounts/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /05_dstagram/accounts/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AccountsConfig(AppConfig): 5 | name = 'accounts' 6 | -------------------------------------------------------------------------------- /05_dstagram/accounts/forms.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.models import User 2 | from django import forms 3 | 4 | # 폼 : 폼태그 -> HTML의 태그 -> 프론트단에서 사용자의 입력을 받는 인터페이스 5 | # 장고의 폼 : HTML의 폼 역할, 데이터 베이스에 저장할 내용을 형식, 제약조건 6 | class RegisterForm(forms.ModelForm): 7 | password = forms.CharField(label='Password', widget=forms.PasswordInput) 8 | password2 = forms.CharField(label='Repeat Password', widget=forms.PasswordInput) 9 | 10 | class Meta: 11 | model = User 12 | fields = ['username', 'first_name', 'last_name', 'email'] 13 | 14 | def clean_password2(self): 15 | cd = self.cleaned_data 16 | if cd['password'] != cd['password2']: 17 | raise forms.ValidationError('Passwords not matched!') 18 | return cd['password2'] -------------------------------------------------------------------------------- /05_dstagram/accounts/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/05_dstagram/accounts/migrations/__init__.py -------------------------------------------------------------------------------- /05_dstagram/accounts/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /05_dstagram/accounts/templates/registration/login.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}- Login{% endblock %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
Please enter your login information.
9 |
10 | {{form.as_p}} 11 | {% csrf_token %} 12 | 13 |
14 |
15 |
16 |
17 | {% endblock %} -------------------------------------------------------------------------------- /05_dstagram/accounts/templates/registration/logout.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}- Logout{% endblock %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
You have been successfully logged out.
9 | Click to Login 10 |
11 |
12 |
13 | {% endblock %} -------------------------------------------------------------------------------- /05_dstagram/accounts/templates/registration/register.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}- Registration{% endblock %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
Please enter your account information.
9 |
10 | {{form.as_p}} 11 | {% csrf_token %} 12 | 13 |
14 |
15 |
16 |
17 | {% endblock %} -------------------------------------------------------------------------------- /05_dstagram/accounts/templates/registration/register_done.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}- Registration Done{% endblock %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
Registration Success. Welcome, {{new_user.username}}
9 | Move to main 10 |
11 |
12 |
13 | {% endblock %} -------------------------------------------------------------------------------- /05_dstagram/accounts/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /05_dstagram/accounts/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from django.contrib.auth import views as auth_view 3 | from .views import * 4 | 5 | # http://127.0.0.1:8000/accounts/profile/ 6 | # 1. profile 만들기 7 | # 2. profile 페이지가 아닌 페이지로 보내기(a. 장고 설정변경, b. 웹 서버에서 설정) 8 | urlpatterns = [ 9 | path('login/', auth_view.LoginView.as_view(), name="login"), 10 | path('logout/', auth_view.LogoutView.as_view(template_name='registration/logout.html'), name="logout"), 11 | path('register/', register, name='register'), 12 | ] -------------------------------------------------------------------------------- /05_dstagram/accounts/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from .forms import RegisterForm 3 | # Create your views here. 4 | # CRUD Create, Update 5 | 6 | def register(request): 7 | if request.method == "POST": 8 | # 회원 가입 데이터 입력 완료 9 | user_form = RegisterForm(request.POST) 10 | if user_form.is_valid(): 11 | new_user = user_form.save(commit=False) 12 | new_user.set_password(user_form.cleaned_data['password']) 13 | new_user.save() 14 | return render(request, 'registration/register_done.html',{'new_user':new_user}) 15 | else: 16 | # 회원 가입 내용을 입력하는 상황 17 | user_form = RegisterForm() 18 | return render(request, 'registration/register.html', {'form':user_form}) -------------------------------------------------------------------------------- /05_dstagram/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/05_dstagram/config/__init__.py -------------------------------------------------------------------------------- /05_dstagram/config/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for config project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /05_dstagram/config/s3media.py: -------------------------------------------------------------------------------- 1 | from storages.backends.s3boto3 import S3Boto3Storage 2 | 3 | class MediaStorage(S3Boto3Storage): 4 | location = 'media' -------------------------------------------------------------------------------- /05_dstagram/config/urls.py: -------------------------------------------------------------------------------- 1 | """config URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | from django.conf.urls.static import static 20 | from django.conf import settings 21 | 22 | urlpatterns = [ 23 | path('admin/', admin.site.urls), 24 | # 127.0.0.1:8000/abcd/ 25 | path('accounts/', include('accounts.urls')), 26 | path('', include('photo.urls')), 27 | ] 28 | 29 | urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 30 | # DEBUG 모드일 때 - static 기능을 사용한다. 31 | # 1. 미디어 파일 서버를 별도로 두고 사용한다. 32 | # 2. 웹서버에서 별도로 서빙 설정을 한다. -------------------------------------------------------------------------------- /05_dstagram/config/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for config project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /05_dstagram/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /05_dstagram/media/photos/2020/05/16/image_02_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/05_dstagram/media/photos/2020/05/16/image_02_01.png -------------------------------------------------------------------------------- /05_dstagram/media/photos/2020/05/16/스크린샷_2016-05-26_오후_5.54.35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/05_dstagram/media/photos/2020/05/16/스크린샷_2016-05-26_오후_5.54.35.png -------------------------------------------------------------------------------- /05_dstagram/media/photos/2020/05/19/스크린샷_2016-05-26_오후_5.54.35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/05_dstagram/media/photos/2020/05/19/스크린샷_2016-05-26_오후_5.54.35.png -------------------------------------------------------------------------------- /05_dstagram/photo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/05_dstagram/photo/__init__.py -------------------------------------------------------------------------------- /05_dstagram/photo/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | from .models import Photo 5 | class PhotoAdmin(admin.ModelAdmin): 6 | list_display = ['id','author','created','updated'] 7 | raw_id_fields = ['author'] 8 | list_filter = ['created','updated','author'] 9 | search_fields = ['text','created','author__username'] 10 | ordering = ['-updated','-created'] 11 | 12 | admin.site.register(Photo, PhotoAdmin) -------------------------------------------------------------------------------- /05_dstagram/photo/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class PhotoConfig(AppConfig): 5 | name = 'photo' 6 | -------------------------------------------------------------------------------- /05_dstagram/photo/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.6 on 2020-05-16 16:17 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='Photo', 19 | fields=[ 20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 21 | ('photo', models.ImageField(default='photos/no_image.png', upload_to='photos/%Y/%m/%d')), 22 | ('text', models.TextField()), 23 | ('created', models.DateTimeField(auto_now_add=True)), 24 | ('updated', models.DateTimeField(auto_now=True)), 25 | ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_photos', to=settings.AUTH_USER_MODEL)), 26 | ], 27 | options={ 28 | 'ordering': ['-updated'], 29 | }, 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /05_dstagram/photo/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/05_dstagram/photo/migrations/__init__.py -------------------------------------------------------------------------------- /05_dstagram/photo/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | 5 | # 1. 모델 : 데이터베이스 저장될 데이터가 있다면 해당 데이터를 묘사한다. 6 | # 2. 뷰(기능) : 계산, 처리 - 실제 기능, 화면 7 | # 3. URL 맵핑 : 라우팅 테이블에 기록한다. urls.py에 기록 - 주소를 지정 8 | # 4. 화면에 보여줄 것이있다 : 템플릿작성(html) 9 | 10 | # 장고의 기본 유저 모델 11 | from django.contrib.auth.models import User 12 | from django.urls import reverse 13 | # 외래키(ForeignKey) - User 테이블에서 해당 유저를 찾을 수 있는 주키 14 | # 주키(PrimaryKey) - User 테이블에 1 admin x x x x 15 | class Photo(models.Model): 16 | author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_photos') 17 | photo = models.ImageField(upload_to='photos/%Y/%m/%d', default='photos/no_image.png') 18 | text = models.TextField() 19 | created = models.DateTimeField(auto_now_add=True) 20 | updated = models.DateTimeField(auto_now=True) 21 | 22 | # makemigrations -> migrate 23 | class Meta: 24 | ordering = ['-updated'] 25 | 26 | def __str__(self): 27 | return self.author.username + " " + self.created.strftime("%Y-%m-%d %H:%M:%S") 28 | 29 | def get_absolute_url(self): 30 | return reverse('photo:photo_detail', args=[self.id]) 31 | 32 | -------------------------------------------------------------------------------- /05_dstagram/photo/templates/photo/delete.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}- Delete{% endblock %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
9 | Do you want to delete {{object}}? 10 |
11 |
12 | {{form.as_p}} 13 | {%csrf_token%} 14 | 15 |
16 |
17 |
18 |
19 | {% endblock %} -------------------------------------------------------------------------------- /05_dstagram/photo/templates/photo/detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %} 3 | {{object.text|truncatechars:10}} 4 | {% endblock %} 5 | 6 | {% block content %} 7 |
8 |
9 |
10 |

11 | 14 |

{{object.text|linebreaksbr}}

15 | Delete 16 | Update 17 |
18 |
19 |
20 |
21 |
22 |
23 | {% load disqus_tags %} 24 | {% disqus_show_comments %} 25 |
26 |
27 |
28 | {% endblock %} -------------------------------------------------------------------------------- /05_dstagram/photo/templates/photo/list.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}- List{% endblock %} 3 | 4 | {% block content %} 5 | {% for post in photos %} 6 |
7 |
8 |
9 |

10 | 13 |

{{post.text|linebreaksbr}}

14 |

15 | 댓글달기 16 |

17 |
18 |
19 |
20 | {% endfor %} 21 | {% endblock %} -------------------------------------------------------------------------------- /05_dstagram/photo/templates/photo/update.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}- Update{% endblock %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
9 | {{form.as_p}} 10 | {%csrf_token%} 11 | 12 |
13 |
14 |
15 |
16 | {% endblock %} -------------------------------------------------------------------------------- /05_dstagram/photo/templates/photo/upload.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}- Upload{% endblock %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
9 | {{form.as_p}} 10 | {%csrf_token%} 11 | 12 |
13 |
14 |
15 |
16 | {% endblock %} -------------------------------------------------------------------------------- /05_dstagram/photo/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /05_dstagram/photo/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from django.views.generic.detail import DetailView 3 | from .views import * 4 | from .models import Photo 5 | # 2차 URL 파일 6 | app_name = 'photo' 7 | 8 | urlpatterns = [ 9 | path('', photo_list, name='photo_list'), 10 | path('detail//', DetailView.as_view(model=Photo, template_name='photo/detail.html'), name='photo_detail'), 11 | path('upload/', PhotoUploadView.as_view(), name='photo_upload'), 12 | path('delete//', PhotoDeleteView.as_view(), name='photo_delete'), 13 | path('update//', PhotoUpdateView.as_view(), name='photo_update'), 14 | ] -------------------------------------------------------------------------------- /05_dstagram/photo/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from django.contrib.auth.decorators import login_required 3 | from django.contrib.auth.mixins import LoginRequiredMixin 4 | # Create your views here. 5 | from .models import Photo 6 | 7 | @login_required 8 | def photo_list(request): 9 | # 보여줄 사진 데이터 10 | photos = Photo.objects.all() 11 | return render(request, 'photo/list.html', {'photos':photos}) 12 | 13 | from django.views.generic.edit import CreateView,DeleteView, UpdateView 14 | from django.shortcuts import redirect 15 | 16 | class PhotoUploadView(LoginRequiredMixin, CreateView): 17 | model = Photo 18 | fields = ['photo', 'text'] # 작성자(author), 작성시간(created) 19 | template_name = 'photo/upload.html' 20 | 21 | def form_valid(self, form): 22 | form.instance.author_id = self.request.user.id 23 | if form.is_valid(): 24 | # 데이터가 올바르다면 25 | form.instance.save() 26 | return redirect('/') 27 | else: 28 | return self.render_to_response({'form':form}) 29 | 30 | class PhotoDeleteView(LoginRequiredMixin, DeleteView): 31 | model = Photo 32 | success_url = '/' 33 | template_name = 'photo/delete.html' 34 | 35 | class PhotoUpdateView(LoginRequiredMixin, UpdateView): 36 | model = Photo 37 | fields = ['photo','text'] 38 | template_name = 'photo/update.html' 39 | 40 | """ 41 | 서버에 이미지 파일을 업로드하거나 수정하거나 지운다. 42 | 장고 웹 앱이 해당 작업을 수행한다. 43 | 장고 웹 앱은 특정 서버에 업로드 되어 있다. 44 | * 그럼 해당 기능은 특정 서버 안에서만 영향을 끼칠 수 있다. 45 | -> 실 서비스를 배포하면 서버 컴퓨터는 1대가 아니다. 46 | -> 사용자가 늘어날 때마다 서버 컴퓨터도 늘어난다. 47 | -> 장고 웹 앱이 업로드 되어있는 서버 컴퓨터가 늘어난다. 48 | -> 이미지 파일이 업로드 되는 컴퓨터의 댓수도 늘어나야 한다. 49 | -> 업로드 받은 후에 다른 서버에도 공유해줘야 한다. 50 | -> 공유해주는데 사용되는 자원(돈이나 시간)이 아깝다. 51 | -> 어떻게하면 공유하는데 들어가는 돈이나 시간을 절약할 수 있을까? 52 | -> 이미지는 한 곳의 서버에다만 올려놓고, 거기에 접속해서 사용하자. 53 | """ -------------------------------------------------------------------------------- /05_dstagram/requirements.txt: -------------------------------------------------------------------------------- 1 | asgiref==3.2.7 2 | boto3==1.13.22 3 | botocore==1.16.22 4 | dj-database-url==0.5.0 5 | Django==3.0.6 6 | django-disqus==0.5 7 | django-storages==1.9.1 8 | docutils==0.15.2 9 | gunicorn==20.0.4 10 | jmespath==0.10.0 11 | mock==4.0.2 12 | Pillow==7.1.2 13 | python-dateutil==2.8.1 14 | pytz==2020.1 15 | s3transfer==0.3.3 16 | six==1.15.0 17 | sqlparse==0.3.1 18 | urllib3==1.25.9 19 | whitenoise==5.1.0 20 | -------------------------------------------------------------------------------- /05_dstagram/runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.7.7 -------------------------------------------------------------------------------- /05_dstagram/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Dstagram {% block title %}{% endblock %} 12 | 13 | 14 | 15 |
16 |
17 | 31 |
32 | {% block content %} 33 | {% endblock %} 34 | 35 |
36 |

© 2020 Baepeu. Powered By Django 3

37 |
38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /06_onlineshop/cart/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/cart/__init__.py -------------------------------------------------------------------------------- /06_onlineshop/cart/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /06_onlineshop/cart/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CartConfig(AppConfig): 5 | name = 'cart' 6 | -------------------------------------------------------------------------------- /06_onlineshop/cart/cart.py: -------------------------------------------------------------------------------- 1 | from decimal import Decimal 2 | from django.conf import settings 3 | 4 | from shop.models import Product 5 | from coupon.models import Coupon 6 | 7 | class Cart(object): 8 | def __init__(self, request): 9 | self.session = request.session 10 | cart = self.session.get(settings.CART_ID) 11 | if not cart: 12 | cart = self.session[settings.CART_ID] = {} 13 | self.cart = cart 14 | self.coupon_id = self.session.get('coupon_id') 15 | 16 | def __len__(self): 17 | return sum(item['quantity'] for item in self.cart.values()) 18 | 19 | def __iter__(self): 20 | product_ids = self.cart.keys() 21 | 22 | products = Product.objects.filter(id__in=product_ids) 23 | 24 | for product in products: 25 | self.cart[str(product.id)]['product'] = product 26 | 27 | for item in self.cart.values(): 28 | item['price'] = Decimal(item['price']) 29 | item['total_price'] = item['price'] * item['quantity'] 30 | 31 | yield item 32 | 33 | def add(self, product, quantity=1, is_update=False): 34 | product_id = str(product.id) 35 | if product_id not in self.cart: 36 | self.cart[product_id] = {'quantity':0, 'price':str(product.price)} 37 | 38 | if is_update: 39 | self.cart[product_id]['quantity'] = quantity 40 | else: 41 | self.cart[product_id]['quantity'] += quantity 42 | 43 | self.save() 44 | 45 | def save(self): 46 | self.session[settings.CART_ID] = self.cart 47 | self.session.modified = True 48 | 49 | def remove(self, product): 50 | product_id = str(product.id) 51 | if product_id in self.cart: 52 | del(self.cart[product_id]) 53 | self.save() 54 | 55 | def clear(self): 56 | self.session[settings.CART_ID] = {} 57 | self.session['coupon_id'] = None 58 | self.session.modified = True 59 | 60 | def get_product_total(self,call='test'): 61 | return sum(Decimal(item['price'])*item['quantity'] for item in self.cart.values()) 62 | 63 | @property 64 | def coupon(self): 65 | if self.coupon_id: 66 | return Coupon.objects.get(id=self.coupon_id) 67 | return None 68 | 69 | def get_discount_total(self): 70 | if self.coupon: 71 | if self.get_product_total() >= self.coupon.amount: 72 | return self.coupon.amount 73 | return Decimal(0) 74 | 75 | def get_total_price(self): 76 | return self.get_product_total() - self.get_discount_total() -------------------------------------------------------------------------------- /06_onlineshop/cart/context_processors.py: -------------------------------------------------------------------------------- 1 | from .cart import Cart 2 | 3 | def cart(request): 4 | cart = Cart(request) 5 | return {'cart':cart} -------------------------------------------------------------------------------- /06_onlineshop/cart/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | # 클라이언트 화면에 입력 폼을 만들어주려고 4 | # 클라이언트가 입력한 데이터에 대한 전처리 5 | 6 | class AddProductForm(forms.Form): 7 | quantity = forms.IntegerField() 8 | is_update = forms.BooleanField(required=False, initial=False, widget=forms.HiddenInput) -------------------------------------------------------------------------------- /06_onlineshop/cart/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/cart/migrations/__init__.py -------------------------------------------------------------------------------- /06_onlineshop/cart/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /06_onlineshop/cart/templates/cart/detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block title %} 4 | Shopping Cart 5 | {% endblock %} 6 | 7 | {% block content %} 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% for item in cart %} 21 | {% with product=item.product %} 22 | 23 | 28 | 29 | 37 | 38 | 39 | 40 | 41 | {% endwith %} 42 | {% endfor %} 43 | {% if cart.coupon %} 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {% endif %} 55 | 56 | 57 | 58 | 59 | 60 | 61 |
ImageProductQuantityRemoveUnit PricePrice
24 | 25 | 26 | 27 | {{product.name}} 30 |
31 | {% csrf_token %} 32 | {{item.quantity_form.quantity}} 33 | {{item.quantity_form.is_update}} 34 | 35 |
36 |
Remove{{item.price}}{{item.total_price}}
Subtotal{{cart.get_product_total|floatformat:"2"}}
{{cart.coupon.code}} coupon ({{cart.coupon.amount}})- {{cart.get_discount_total|floatformat:"2"}}
Total{{cart.get_total_price|floatformat:"2"}}
62 |

63 | Add Coupon: 64 |

65 |
66 | {% csrf_token %} 67 | {{add_coupon}} 68 | 69 |
70 |

71 | Continue shopping 72 | 73 | Checkout 74 |

75 | {% endblock %} -------------------------------------------------------------------------------- /06_onlineshop/cart/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /06_onlineshop/cart/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from .views import * 3 | 4 | app_name = 'cart' 5 | 6 | urlpatterns = [ 7 | path('', detail, name='detail'), 8 | path('add//', add, name='product_add'), 9 | path('remove//', remove, name='product_remove'), 10 | ] -------------------------------------------------------------------------------- /06_onlineshop/cart/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, redirect, get_object_or_404 2 | from django.views.decorators.http import require_POST 3 | # Create your views here. 4 | 5 | from shop.models import Product 6 | from coupon.forms import AddCouponForm 7 | 8 | from .forms import AddProductForm 9 | from .cart import Cart 10 | 11 | @require_POST 12 | def add(request, product_id): 13 | cart = Cart(request) 14 | product = get_object_or_404(Product, id=product_id) 15 | 16 | # 클라이언 -> 서버로 데이터를 전달 17 | # 유효성 검사, injection 전처리 18 | form = AddProductForm(request.POST) 19 | 20 | if form.is_valid(): 21 | cd = form.cleaned_data 22 | cart.add(product=product, quantity=cd['quantity'], is_update=cd['is_update']) 23 | 24 | return redirect('cart:detail') 25 | 26 | def remove(request, product_id): 27 | cart = Cart(request) 28 | product = get_object_or_404(Product, id=product_id) 29 | cart.remove(product) 30 | return redirect('cart:detail') 31 | 32 | def detail(request): 33 | cart = Cart(request) 34 | add_coupon = AddCouponForm() 35 | for product in cart: 36 | product['quantity_form'] = AddProductForm(initial={'quantity':product['quantity'], 'is_update':True}) 37 | 38 | return render(request, 'cart/detail.html', {'cart':cart, 39 | 'add_coupon':add_coupon 40 | }) -------------------------------------------------------------------------------- /06_onlineshop/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/config/__init__.py -------------------------------------------------------------------------------- /06_onlineshop/config/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for config project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /06_onlineshop/config/s3_media_upload.py: -------------------------------------------------------------------------------- 1 | __author__ = 'Jake Song' 2 | __copyright__ = 'Copyright 2020, Beapeu Book' 3 | __credits__ = ['Jake Song'] 4 | __license__ = 'GPL' 5 | __version__ = '1.0.0' 6 | __maintainer__ = 'Jake Song' 7 | __email__ = 'beap.jg@gmail.com' 8 | __status__ = 'Production' 9 | # This module for uploading media files in django project to AWS S3 with Django Default Storage Class. 10 | 11 | import os, sys, django 12 | 13 | from django.core.files.storage import get_storage_class 14 | 15 | sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 16 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") 17 | django.setup() 18 | 19 | def upload_files(path): 20 | default_storage = get_storage_class()() 21 | 22 | for subdir, dirs, files in os.walk(path): 23 | for file in files: 24 | full_path = os.path.join(subdir, file) 25 | with open(full_path, 'rb') as data: 26 | default_storage.save(full_path.replace("\\","/")[len(path) + 1:], data) 27 | 28 | if __name__ == "__main__": 29 | upload_files('media') -------------------------------------------------------------------------------- /06_onlineshop/config/s3media.py: -------------------------------------------------------------------------------- 1 | from storages.backends.s3boto3 import S3Boto3Storage 2 | 3 | class MediaStorage(S3Boto3Storage): 4 | location = "" 5 | bucket_name = 'onlineshop-media' 6 | region_name = 'ap-northeast-2' 7 | custom_domain = f"s3.{region_name}.amazonaws.com/{bucket_name}" 8 | file_overwrite = False -------------------------------------------------------------------------------- /06_onlineshop/config/urls.py: -------------------------------------------------------------------------------- 1 | """config URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | urlpatterns = [ 20 | path('admin/', admin.site.urls), 21 | path('accounts/', include('allauth.urls')), 22 | path('cart/', include('cart.urls')), 23 | path('coupon/', include('coupon.urls')), 24 | path('order/', include('order.urls')), 25 | path('', include('shop.urls')), 26 | ] 27 | -------------------------------------------------------------------------------- /06_onlineshop/config/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for config project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /06_onlineshop/coupon/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/coupon/__init__.py -------------------------------------------------------------------------------- /06_onlineshop/coupon/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Coupon 3 | # Register your models here. 4 | 5 | class CouponAdmin(admin.ModelAdmin): 6 | list_display = ['code', 'use_from', 'use_to', 'amount', 'active'] 7 | list_filter = ['active', 'use_from', 'use_to'] 8 | search_fields = ['code'] 9 | 10 | admin.site.register(Coupon, CouponAdmin) 11 | -------------------------------------------------------------------------------- /06_onlineshop/coupon/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CouponConfig(AppConfig): 5 | name = 'coupon' 6 | -------------------------------------------------------------------------------- /06_onlineshop/coupon/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | class AddCouponForm(forms.Form): 4 | code = forms.CharField(label='Your Coupon Code') -------------------------------------------------------------------------------- /06_onlineshop/coupon/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.7 on 2020-07-06 10:35 2 | 3 | import django.core.validators 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | initial = True 10 | 11 | dependencies = [ 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Coupon', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('code', models.CharField(max_length=50, unique=True)), 20 | ('use_from', models.DateTimeField()), 21 | ('use_to', models.DateTimeField()), 22 | ('amount', models.IntegerField(validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000)])), 23 | ('active', models.BooleanField()), 24 | ], 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /06_onlineshop/coupon/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/coupon/migrations/__init__.py -------------------------------------------------------------------------------- /06_onlineshop/coupon/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.core.validators import MinValueValidator, MaxValueValidator 3 | # Create your models here. 4 | 5 | class Coupon(models.Model): 6 | code = models.CharField(max_length=50, unique=True) 7 | use_from = models.DateTimeField() 8 | use_to = models.DateTimeField() 9 | amount = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(100000)]) 10 | active = models.BooleanField() 11 | 12 | def __str__(self): 13 | return self.code -------------------------------------------------------------------------------- /06_onlineshop/coupon/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /06_onlineshop/coupon/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from .views import add_coupon 4 | app_name = 'coupon' 5 | 6 | urlpatterns = [ 7 | path('add/', add_coupon, name='add'), 8 | ] -------------------------------------------------------------------------------- /06_onlineshop/coupon/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | from django.shortcuts import redirect 4 | from django.utils import timezone 5 | from django.views.decorators.http import require_POST 6 | 7 | from .models import Coupon 8 | from .forms import AddCouponForm 9 | # Create your views here. 10 | 11 | @require_POST 12 | def add_coupon(request): 13 | now = timezone.now() 14 | form = AddCouponForm(request.POST) 15 | if form.is_valid(): 16 | code = form.cleaned_data['code'] 17 | 18 | try: 19 | coupon = Coupon.objects.get(code__iexact=code, use_from__lte=now, use_to__gte=now, active=True) 20 | request.session['coupon_id'] = coupon.id 21 | except Coupon.DoesNotExist: 22 | request.session['coupon_id'] = None 23 | 24 | return redirect('cart:detail') 25 | -------------------------------------------------------------------------------- /06_onlineshop/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /06_onlineshop/order/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/order/__init__.py -------------------------------------------------------------------------------- /06_onlineshop/order/admin.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import datetime 3 | from django.contrib import admin 4 | from .models import Order, OrderItem 5 | from django.http import HttpResponse 6 | 7 | def export_to_csv(modeladmin, request, queryset): 8 | opts = modeladmin.model._meta 9 | response = HttpResponse(content_type='text/csv') 10 | response['Content-Disposition'] = 'attachment;filename={}.csv'.format(opts.verbose_name) 11 | 12 | writer = csv.writer(response) 13 | fields = [field for field in opts.get_fields() if not field.many_to_many and not field.one_to_many] 14 | 15 | writer.writerow([field.verbose_name for field in fields]) 16 | 17 | for obj in queryset: 18 | data_row = [] 19 | for field in fields: 20 | value = getattr(obj, field.name) 21 | if isinstance(value, datetime.datetime): 22 | value = value.strftime("%Y-%m-%d") 23 | data_row.append(value) 24 | writer.writerow(data_row) 25 | return response 26 | export_to_csv.short_description = 'Export to CSV' 27 | 28 | class OrderItemInline(admin.TabularInline): 29 | model = OrderItem 30 | raw_id_fields = ['product'] 31 | 32 | from django.urls import reverse 33 | from django.utils.safestring import mark_safe 34 | 35 | def order_detail(obj): 36 | url = reverse('orders:admin_order_detail', args=[obj.id]) 37 | html = mark_safe(f"Detail") 38 | return html 39 | order_detail.short_description = 'Detail' 40 | 41 | def order_pdf(obj): 42 | url = reverse('orders:admin_order_pdf', args=[obj.id]) 43 | html = mark_safe(f"PDF") 44 | return html 45 | 46 | order_pdf.short_description = 'PDF' 47 | 48 | class OrderAdmin(admin.ModelAdmin): 49 | list_display = ['id','first_name','last_name', 'email','address','postal_code','city','paid',order_detail,order_pdf,'created','updated'] 50 | list_filter = ['paid','created','updated'] 51 | inlines = [OrderItemInline] 52 | actions = [export_to_csv] 53 | 54 | admin.site.register(Order, OrderAdmin) 55 | -------------------------------------------------------------------------------- /06_onlineshop/order/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class OrderConfig(AppConfig): 5 | name = 'order' 6 | -------------------------------------------------------------------------------- /06_onlineshop/order/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | from .models import Order 4 | 5 | class OrderCreateForm(forms.ModelForm): 6 | class Meta: 7 | model = Order 8 | fields = ['first_name','last_name','email','address', 9 | 'postal_code','city'] -------------------------------------------------------------------------------- /06_onlineshop/order/iamport.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from django.conf import settings 3 | 4 | def get_token(): 5 | access_data = { 6 | 'imp_key':settings.IAMPORT_KEY, 7 | 'imp_secret':settings.IAMPORT_SECRET 8 | } 9 | url = "https://api.iamport.kr/users/getToken" 10 | req = requests.post(url, data=access_data) 11 | access_res = req.json() 12 | 13 | if access_res['code'] is 0: 14 | return access_res['response']['access_token'] 15 | else: 16 | return None 17 | 18 | def payments_prepare(order_id, amount, *args, **kwargs): 19 | access_token = get_token() 20 | if access_token: 21 | access_data = { 22 | 'merchant_uid':order_id, 23 | 'amount':amount 24 | } 25 | url = "https://api.iamport.kr/payments/prepare" 26 | headers = { 27 | 'Authorization':access_token 28 | } 29 | req = requests.post(url, data=access_data, headers=headers) 30 | res = req.json() 31 | if res['code'] != 0: 32 | raise ValueError("API 통신 오류") 33 | else: 34 | raise ValueError("토큰 오류") 35 | 36 | 37 | 38 | def find_transaction(order_id, *args, **kwargs): 39 | access_token = get_token() 40 | if access_token: 41 | url = "https://api.iamport.kr/payments/find/"+order_id 42 | headers = { 43 | 'Authorization':access_token 44 | } 45 | req = requests.post(url, headers=headers) 46 | res = req.json() 47 | if res['code'] == 0: 48 | context = { 49 | 'imp_id':res['response']['imp_uid'], 50 | 'merchant_order_id':res['response']['merchant_uid'], 51 | 'amount':res['response']['amount'], 52 | 'status':res['response']['status'], 53 | 'type':res['response']['pay_method'], 54 | 'receipt_url':res['response']['receipt_url'] 55 | } 56 | return context 57 | else: 58 | return None 59 | else: 60 | raise ValueError("토큰 오류") -------------------------------------------------------------------------------- /06_onlineshop/order/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.7 on 2020-07-19 15:30 2 | 3 | import django.core.validators 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ('coupon', '0001_initial'), 14 | ('shop', '0001_initial'), 15 | ] 16 | 17 | operations = [ 18 | migrations.CreateModel( 19 | name='Order', 20 | fields=[ 21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 22 | ('first_name', models.CharField(max_length=50)), 23 | ('last_name', models.CharField(max_length=50)), 24 | ('email', models.EmailField(max_length=254)), 25 | ('address', models.CharField(max_length=250)), 26 | ('postal_code', models.CharField(max_length=20)), 27 | ('city', models.CharField(max_length=100)), 28 | ('created', models.DateTimeField(auto_now_add=True)), 29 | ('updated', models.DateTimeField(auto_now=True)), 30 | ('paid', models.BooleanField(default=False)), 31 | ('discount', models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000)])), 32 | ('coupon', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='order_coupon', to='coupon.Coupon')), 33 | ], 34 | options={ 35 | 'ordering': ['-created'], 36 | }, 37 | ), 38 | migrations.CreateModel( 39 | name='OrderTransaction', 40 | fields=[ 41 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 42 | ('merchant_order_id', models.CharField(blank=True, max_length=120, null=True)), 43 | ('transaction_id', models.CharField(blank=True, max_length=120, null=True)), 44 | ('amount', models.DecimalField(decimal_places=2, default=0, max_digits=10)), 45 | ('transaction_status', models.CharField(blank=True, max_length=220, null=True)), 46 | ('type', models.CharField(blank=True, max_length=120)), 47 | ('created', models.DateTimeField(auto_now_add=True)), 48 | ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='order.Order')), 49 | ], 50 | options={ 51 | 'ordering': ['-created'], 52 | }, 53 | ), 54 | migrations.CreateModel( 55 | name='OrderItem', 56 | fields=[ 57 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 58 | ('price', models.DecimalField(decimal_places=2, max_digits=10)), 59 | ('quantity', models.PositiveIntegerField(default=1)), 60 | ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='order.Order')), 61 | ('product', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='order_products', to='shop.Product')), 62 | ], 63 | ), 64 | ] 65 | -------------------------------------------------------------------------------- /06_onlineshop/order/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/order/migrations/__init__.py -------------------------------------------------------------------------------- /06_onlineshop/order/templates/order/admin/detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/base_site.html' %} 2 | {% block title %} 3 | Order {{order.id}} Detail 4 | {% endblock %} 5 | 6 | {% block breadcrumbs %} 7 | 12 | {% endblock %} 13 | 14 | {% block content %} 15 |

Order {{order.id}}

16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
Created{{order.created}}
Customer{{order.first_name}} {{order.last_name}}
E-mail{{order.email}}
Address{{order.address}} {{order.postal_code}} {{order.city}}
Total amount{{order.get_total_price}}
43 | {% endblock %} -------------------------------------------------------------------------------- /06_onlineshop/order/templates/order/admin/pdf.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Django OnlineShop

4 |

5 | Invoice no. {{order.id}}
6 | {{order.created|date:"M d, Y"}} 7 |

8 |

{% if order.paid %}Payment Accepted{%else%}Pending payment{%endif%}

9 |

10 | {{order.first_name}} {{order.last_name}}
11 | {{order.email}}
12 | {{order.address}}
13 | {{order.postal_code}}, {{order.city}}
14 |

15 |

Product List

16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% for item in order.items.all %} 27 | 28 | 29 | 30 | 31 | 32 | 33 | {% endfor %} 34 | {% if order.coupon %} 35 | 36 | 37 | 38 | 39 | {%endif%} 40 | 41 | 42 | 43 | 44 | 45 |
ProductPriceQuantityCost
{{item.product.name}}{{item.price}}{{item.quantity}}{{item.get_item_price}}
Discount{{order.discount}}
Total{{order.get_total_price}}
46 | 47 | -------------------------------------------------------------------------------- /06_onlineshop/order/templates/order/create.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block title %} 4 | Checkout 5 | {% endblock %} 6 | 7 | {% block script %} 8 | 15 | 16 | 17 | 18 | {% load static %} 19 | 20 | {% endblock %} 21 | 22 | {% block content %} 23 |
24 |
25 | 26 |
    27 | {% for item in cart %} 28 |
  • 29 | {{item.quantity}}X{{item.product.name}} 30 | {{item.total_price}} 31 |
  • 32 | {% endfor %} 33 | {% if cart.coupon %} 34 |
  • 35 | "{{cart.coupon.code}}" (${{cart.coupon.amount}} off) 36 | - ${{cart.get_total_discount|floatformat:"2"}} 37 |
  • 38 | {% endif %} 39 |
40 | 41 |
42 | {{form.as_p}} 43 | {% csrf_token %} 44 | 45 | 46 | 47 |
48 |
49 |
50 | {% endblock %} -------------------------------------------------------------------------------- /06_onlineshop/order/templates/order/created.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block title %} 4 | Order Complete! 5 | {% endblock %} 6 | 7 | {% block content %} 8 |
9 |
10 | 11 | 12 |
13 |
14 | {% endblock %} -------------------------------------------------------------------------------- /06_onlineshop/order/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /06_onlineshop/order/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from .views import * 3 | app_name = 'orders' 4 | urlpatterns = [ 5 | path('create/', order_create, name='order_create'), 6 | path('create_ajax/', OrderCreateAjaxView.as_view(), name='order_create_ajax'), 7 | path('checkout/', OrderCheckoutAjaxView.as_view(), name='order_checkout'), 8 | path('validation/', OrderImpAjaxView.as_view(), name='order_validation'), 9 | path('complete/', order_complete, name='order_complete'), 10 | path('order_detail//', admin_order_detail,name='admin_order_detail'), 11 | path('order_pdf//', admin_order_pdf,name='admin_order_pdf'), 12 | ] -------------------------------------------------------------------------------- /06_onlineshop/products/2020/06/26/mbp13touch-space-select-202005_GEO_KR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/products/2020/06/26/mbp13touch-space-select-202005_GEO_KR.jpg -------------------------------------------------------------------------------- /06_onlineshop/requirements.txt: -------------------------------------------------------------------------------- 1 | asgiref==3.2.7 2 | boto3==1.14.11 3 | botocore==1.17.11 4 | certifi==2020.6.20 5 | chardet==3.0.4 6 | defusedxml==0.6.0 7 | Django==3.0.7 8 | django-allauth==0.42.0 9 | django-storages==1.9.1 10 | docutils==0.15.2 11 | idna==2.9 12 | jmespath==0.10.0 13 | oauthlib==3.1.0 14 | Pillow==7.1.2 15 | PyMySQL==0.9.3 16 | python-dateutil==2.8.1 17 | python3-openid==3.1.0 18 | pytz==2020.1 19 | requests==2.24.0 20 | requests-oauthlib==1.3.0 21 | s3transfer==0.3.3 22 | six==1.15.0 23 | sqlparse==0.3.1 24 | urllib3==1.25.9 25 | -------------------------------------------------------------------------------- /06_onlineshop/shop/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/shop/__init__.py -------------------------------------------------------------------------------- /06_onlineshop/shop/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import * 3 | # Register your models here. 4 | 5 | class CategoryAdmin(admin.ModelAdmin): 6 | list_display = ['id','name','slug'] 7 | prepopulated_fields = {'slug':['name']} 8 | 9 | admin.site.register(Category, CategoryAdmin) 10 | 11 | @admin.register(Product) 12 | class ProductAdmin(admin.ModelAdmin): 13 | list_display = ['id','name','slug','category','price','stock','available_display','available_order','created','updated'] 14 | list_filter = ['available_display','created','updated','category'] 15 | prepopulated_fields = {'slug':('name',)} 16 | list_editable = ['price','stock','available_display','available_order'] 17 | -------------------------------------------------------------------------------- /06_onlineshop/shop/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ShopConfig(AppConfig): 5 | name = 'shop' 6 | -------------------------------------------------------------------------------- /06_onlineshop/shop/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.7 on 2020-06-16 15:26 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | initial = True 10 | 11 | dependencies = [ 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Category', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('name', models.CharField(db_index=True, max_length=200)), 20 | ('meta_description', models.TextField(blank=True)), 21 | ('slug', models.SlugField(allow_unicode=True, max_length=200, unique=True)), 22 | ], 23 | options={ 24 | 'verbose_name': 'category', 25 | 'verbose_name_plural': 'categories', 26 | 'ordering': ['name'], 27 | }, 28 | ), 29 | migrations.CreateModel( 30 | name='Product', 31 | fields=[ 32 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 33 | ('name', models.CharField(db_index=True, max_length=200)), 34 | ('slug', models.SlugField(allow_unicode=True, max_length=200, unique=True)), 35 | ('image', models.ImageField(blank=True, upload_to='products/%Y/%m/%d')), 36 | ('description', models.TextField(blank=True)), 37 | ('meta_description', models.TextField(blank=True)), 38 | ('price', models.DecimalField(decimal_places=2, max_digits=10)), 39 | ('stock', models.PositiveIntegerField()), 40 | ('available_display', models.BooleanField(default=True, verbose_name='Display')), 41 | ('available_order', models.BooleanField(default=True, verbose_name='Order')), 42 | ('created', models.DateTimeField(auto_now_add=True)), 43 | ('updated', models.DateTimeField(auto_now=True)), 44 | ('category', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='products', to='shop.Category')), 45 | ], 46 | options={ 47 | 'ordering': ['-created', '-updated'], 48 | 'index_together': {('id', 'slug')}, 49 | }, 50 | ), 51 | ] 52 | -------------------------------------------------------------------------------- /06_onlineshop/shop/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/06_onlineshop/shop/migrations/__init__.py -------------------------------------------------------------------------------- /06_onlineshop/shop/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.urls import reverse 3 | 4 | # Create your models here. 5 | class Category(models.Model): 6 | name = models.CharField(max_length=200, db_index=True) 7 | meta_description = models.TextField(blank=True) 8 | slug = models.SlugField(max_length=200, db_index=True, unique=True, allow_unicode=True) 9 | 10 | class Meta: 11 | ordering = ['name'] 12 | verbose_name = 'category' 13 | verbose_name_plural = 'categories' 14 | 15 | def __str__(self): 16 | return self.name 17 | 18 | def get_absolute_url(self): 19 | return reverse('shop:product_in_category', args=[self.slug]) 20 | 21 | class Product(models.Model): 22 | category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='products') 23 | name = models.CharField(max_length=200, db_index=True) 24 | slug = models.SlugField(max_length=200, db_index=True, unique=True, allow_unicode=True) 25 | image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True) 26 | description = models.TextField(blank=True) 27 | meta_description = models.TextField(blank=True) 28 | price = models.DecimalField(max_digits=10, decimal_places=2) 29 | stock = models.PositiveIntegerField() 30 | available_display = models.BooleanField('Display', default=True) 31 | available_order = models.BooleanField('Order', default=True) 32 | 33 | created = models.DateTimeField(auto_now_add=True) 34 | updated = models.DateTimeField(auto_now=True) 35 | 36 | class Meta: 37 | ordering = ['-created', '-updated'] 38 | index_together = [['id','slug']] 39 | 40 | def __str__(self): 41 | return self.name 42 | 43 | def get_absolute_url(self): 44 | return reverse('shop:product_detail', args=[self.id, self.slug]) -------------------------------------------------------------------------------- /06_onlineshop/shop/templates/shop/detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block title %}Product Detail 4 | {% endblock %} 5 | 6 | {% block content %} 7 |
8 |
9 | 10 |
11 |
12 |

{{product.name}}

13 |

Price{{product.price}}

14 | 15 |
16 | {{add_to_cart}} 17 | {% csrf_token %} 18 | 19 |
20 | 21 |
Description{{product.description|linebreaks}}
22 |
23 |
24 | {% endblock %} -------------------------------------------------------------------------------- /06_onlineshop/shop/templates/shop/list.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block title %}Category Page 4 | {% endblock %} 5 | 6 | {% block content %} 7 |
8 |
9 |
10 | All 11 | {% for c in categories %} 12 | {{c.name}} 13 | {% endfor %} 14 |
15 |
16 |
17 |
18 | {% if current_category %}{{current_category.name}}{% else %}All Products{% endif %} 19 |
20 |
21 | {% for product in products %} 22 |
23 |
24 | {%if product.image%}Product Image{%endif%} 25 |
26 |
{{product.name}}
27 |

{{product.description}} {{product.price}}

28 | View Detail 29 |
30 |
31 |
32 | {% endfor %} 33 |
34 |
35 | 36 |
37 | {% endblock %} -------------------------------------------------------------------------------- /06_onlineshop/shop/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /06_onlineshop/shop/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from .views import * 3 | 4 | app_name = 'shop' 5 | 6 | urlpatterns = [ 7 | path('', product_in_category, name='product_all'), 8 | path('/', product_in_category, name='product_in_category'), 9 | path('//', product_detail, name='product_detail'), 10 | ] -------------------------------------------------------------------------------- /06_onlineshop/shop/views.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | 4 | from django.shortcuts import render, get_object_or_404 5 | 6 | # Create your views here. 7 | from .models import * 8 | from cart.forms import AddProductForm 9 | 10 | def product_in_category(request, category_slug=None): 11 | current_category = None 12 | categories = Category.objects.all() 13 | products = Product.objects.filter(available_display=True) 14 | if category_slug: 15 | current_category = get_object_or_404(Category, slug=category_slug) 16 | products = products.filter(category=current_category) 17 | return render(request, 18 | 'shop/list.html', 19 | { 20 | 'current_category':current_category, 21 | 'categories':categories, 22 | 'products':products 23 | }) 24 | 25 | def product_detail(request, id, product_slug=None): 26 | product = get_object_or_404(Product, id=id, slug=product_slug) 27 | add_to_cart = AddProductForm(initial={'quantity':1}) 28 | return render(request, 'shop/detail.html', {'product':product, 'add_to_cart':add_to_cart}) 29 | -------------------------------------------------------------------------------- /06_onlineshop/static/css/pdf.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family:Helvetica, sans-serif; 3 | color:#222; 4 | line-height:1.5em; 5 | } 6 | 7 | table { 8 | width:100%; 9 | border-spacing:0; 10 | border-collapse:collapse; 11 | margin:20px 0; 12 | } 13 | 14 | table th, table td { 15 | text-align:left; 16 | font-size:14px; 17 | padding:10px; 18 | margin:0; 19 | } 20 | 21 | tbody tr:nth-child(odd) { 22 | background:#efefef; 23 | } 24 | 25 | thead th, tbody tr.discount { 26 | background:#46a500; 27 | color:#fff; 28 | font-weight:bold; 29 | } 30 | 31 | tbody tr.total { 32 | background:#5993bb; 33 | color:#fff; 34 | font-weight:bold; 35 | } 36 | 37 | h1 { 38 | margin:0; 39 | } 40 | 41 | .secondary { 42 | color:#bbb; 43 | margin-bottom:20px; 44 | } 45 | 46 | .num { 47 | text-align:right; 48 | } -------------------------------------------------------------------------------- /06_onlineshop/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% block title %}{% endblock %} 6 | 7 | 8 | 9 | 10 | 11 | {% block script %} 12 | {% endblock %} 13 | 14 | {% block style %} 15 | {% endblock %} 16 | 17 | 18 | 48 |
49 | {% block content %} 50 | {% endblock %} 51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /08_booking/booking/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/08_booking/booking/__init__.py -------------------------------------------------------------------------------- /08_booking/booking/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Booking 3 | # Register your models here. 4 | 5 | class BookingAdmin(admin.ModelAdmin): 6 | list_display = ['id','subscriber','room','date_from', 'date_to', 'created','updated'] 7 | list_editable = ['room', 'date_from', 'date_to'] 8 | raw_id_fields = ['subscriber'] 9 | 10 | admin.site.register(Booking, BookingAdmin) 11 | -------------------------------------------------------------------------------- /08_booking/booking/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BookingConfig(AppConfig): 5 | name = 'booking' 6 | -------------------------------------------------------------------------------- /08_booking/booking/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.8 on 2020-07-13 12:44 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='Booking', 19 | fields=[ 20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 21 | ('date_from', models.DateTimeField()), 22 | ('date_to', models.DateTimeField(blank=True, null=True)), 23 | ('room', models.CharField(max_length=100)), 24 | ('note', models.TextField()), 25 | ('created', models.DateTimeField(auto_now_add=True)), 26 | ('updated', models.DateTimeField(auto_now=True)), 27 | ('subscriber', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='bookings', to=settings.AUTH_USER_MODEL)), 28 | ], 29 | options={ 30 | 'ordering': ['-date_from'], 31 | }, 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /08_booking/booking/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/08_booking/booking/migrations/__init__.py -------------------------------------------------------------------------------- /08_booking/booking/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.conf import settings 3 | # Create your models here. 4 | class Booking(models.Model): 5 | subscriber = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name='bookings') 6 | 7 | date_from = models.DateTimeField() 8 | date_to = models.DateTimeField(null=True, blank=True) 9 | room = models.CharField(max_length=100) 10 | note = models.TextField() 11 | 12 | created = models.DateTimeField(auto_now_add=True) 13 | updated = models.DateTimeField(auto_now=True) 14 | 15 | def __str__(self): 16 | return self.subscriber.username + " " + self.room 17 | 18 | class Meta: 19 | ordering = ['-date_from'] 20 | -------------------------------------------------------------------------------- /08_booking/booking/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | from .models import Booking 3 | 4 | class BookingSerializer(serializers.ModelSerializer): 5 | class Meta: 6 | model = Booking 7 | fields = '__all__' -------------------------------------------------------------------------------- /08_booking/booking/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /08_booking/booking/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from rest_framework.urlpatterns import format_suffix_patterns 3 | from .views import * 4 | urlpatterns = [ 5 | path('booking/', BookingList.as_view()), 6 | path('booking//', BookingDetail.as_view()), 7 | ] -------------------------------------------------------------------------------- /08_booking/booking/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from rest_framework import generics 3 | from .models import Booking 4 | from .serializers import BookingSerializer 5 | # Create your views here. 6 | 7 | class BookingList(generics.ListCreateAPIView): 8 | queryset = Booking.objects.all() 9 | serializer_class = BookingSerializer 10 | 11 | class BookingDetail(generics.RetrieveUpdateDestroyAPIView): 12 | queryset = Booking.objects.all() 13 | serializer_class = BookingSerializer 14 | -------------------------------------------------------------------------------- /08_booking/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/08_booking/config/__init__.py -------------------------------------------------------------------------------- /08_booking/config/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for config project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /08_booking/config/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for config project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.0.3. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.0/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'mgtd6#5vz9zlss9+q=ea3m1_b9o(0t!!7j@zp@20td5d^h&r@a' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'booking', 41 | 'rest_framework', 42 | 'rest_framework_swagger', 43 | ] 44 | 45 | MIDDLEWARE = [ 46 | 'django.middleware.security.SecurityMiddleware', 47 | 'django.contrib.sessions.middleware.SessionMiddleware', 48 | 'django.middleware.common.CommonMiddleware', 49 | 'django.middleware.csrf.CsrfViewMiddleware', 50 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 51 | 'django.contrib.messages.middleware.MessageMiddleware', 52 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 53 | ] 54 | 55 | ROOT_URLCONF = 'config.urls' 56 | 57 | TEMPLATES = [ 58 | { 59 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 60 | 'DIRS': [], 61 | 'APP_DIRS': True, 62 | 'OPTIONS': { 63 | 'context_processors': [ 64 | 'django.template.context_processors.debug', 65 | 'django.template.context_processors.request', 66 | 'django.contrib.auth.context_processors.auth', 67 | 'django.contrib.messages.context_processors.messages', 68 | ], 69 | }, 70 | }, 71 | ] 72 | 73 | WSGI_APPLICATION = 'config.wsgi.application' 74 | 75 | 76 | # Database 77 | # https://docs.djangoproject.com/en/3.0/ref/settings/#databases 78 | 79 | DATABASES = { 80 | 'default': { 81 | 'ENGINE': 'django.db.backends.sqlite3', 82 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 83 | } 84 | } 85 | 86 | 87 | # Password validation 88 | # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators 89 | 90 | AUTH_PASSWORD_VALIDATORS = [ 91 | { 92 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 93 | }, 94 | { 95 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 96 | }, 97 | { 98 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 99 | }, 100 | { 101 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 102 | }, 103 | ] 104 | 105 | 106 | # Internationalization 107 | # https://docs.djangoproject.com/en/3.0/topics/i18n/ 108 | 109 | LANGUAGE_CODE = 'en-us' 110 | 111 | TIME_ZONE = 'UTC' 112 | 113 | USE_I18N = True 114 | 115 | USE_L10N = True 116 | 117 | USE_TZ = True 118 | 119 | 120 | # Static files (CSS, JavaScript, Images) 121 | # https://docs.djangoproject.com/en/3.0/howto/static-files/ 122 | 123 | STATIC_URL = '/static/' 124 | 125 | REST_FRAMEWORK = { 126 | 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema' 127 | } -------------------------------------------------------------------------------- /08_booking/config/urls.py: -------------------------------------------------------------------------------- 1 | """config URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | from rest_framework_swagger.views import get_swagger_view 19 | urlpatterns = [ 20 | path('admin/', admin.site.urls), 21 | path('api/doc/', get_swagger_view(title='Booking API Manual')), 22 | path('', include('booking.urls')), 23 | ] 24 | -------------------------------------------------------------------------------- /08_booking/config/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for config project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /08_booking/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /django_basic/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baepeu/python_web_programming_django3/b2490d5c0ba320304a42408f9fc0ebc5e6c889b0/django_basic/config/__init__.py -------------------------------------------------------------------------------- /django_basic/config/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for config project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /django_basic/config/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for config project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.0.5. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.0/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'i_*00g5+^w98*f4iyow%y=l4m29wdnj)wsi58mkj6803luu+ym' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | ] 41 | 42 | MIDDLEWARE = [ 43 | 'django.middleware.security.SecurityMiddleware', 44 | 'django.contrib.sessions.middleware.SessionMiddleware', 45 | 'django.middleware.common.CommonMiddleware', 46 | 'django.middleware.csrf.CsrfViewMiddleware', 47 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 48 | 'django.contrib.messages.middleware.MessageMiddleware', 49 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 50 | ] 51 | 52 | ROOT_URLCONF = 'config.urls' 53 | 54 | TEMPLATES = [ 55 | { 56 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 57 | 'DIRS': [ 58 | os.path.join(BASE_DIR, 'templates') 59 | ], 60 | 'APP_DIRS': True, 61 | 'OPTIONS': { 62 | 'context_processors': [ 63 | 'django.template.context_processors.debug', 64 | 'django.template.context_processors.request', 65 | 'django.contrib.auth.context_processors.auth', 66 | 'django.contrib.messages.context_processors.messages', 67 | ], 68 | }, 69 | }, 70 | ] 71 | 72 | WSGI_APPLICATION = 'config.wsgi.application' 73 | 74 | 75 | # Database 76 | # https://docs.djangoproject.com/en/3.0/ref/settings/#databases 77 | 78 | DATABASES = { 79 | 'default': { 80 | 'ENGINE': 'django.db.backends.sqlite3', 81 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 82 | } 83 | } 84 | 85 | 86 | # Password validation 87 | # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators 88 | 89 | AUTH_PASSWORD_VALIDATORS = [ 90 | { 91 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 92 | }, 93 | { 94 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 95 | }, 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 98 | }, 99 | { 100 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 101 | }, 102 | ] 103 | 104 | 105 | # Internationalization 106 | # https://docs.djangoproject.com/en/3.0/topics/i18n/ 107 | 108 | LANGUAGE_CODE = 'en-us' 109 | 110 | TIME_ZONE = 'UTC' 111 | 112 | USE_I18N = True 113 | 114 | USE_L10N = True 115 | 116 | USE_TZ = True 117 | 118 | 119 | # Static files (CSS, JavaScript, Images) 120 | # https://docs.djangoproject.com/en/3.0/howto/static-files/ 121 | 122 | STATIC_URL = '/static/' 123 | -------------------------------------------------------------------------------- /django_basic/config/urls.py: -------------------------------------------------------------------------------- 1 | """config URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path 18 | from .views import index, welcome, template_test 19 | urlpatterns = [ 20 | path('admin/', admin.site.urls), 21 | path('welcome/', welcome), 22 | path('test/', template_test), 23 | path('', index), 24 | # path(주소, 뷰, 주소의 별명) 25 | ] 26 | -------------------------------------------------------------------------------- /django_basic/config/views.py: -------------------------------------------------------------------------------- 1 | # 뷰 : 기능을 담당(페이지 단위) 2 | # 화면이 나타나는 뷰, 화면이 없는 뷰 3 | # 화면이 있건 없건 주소 URL은 있어야 한다. 4 | 5 | # 뷰 내용(함수, 클래스), URL이 있으면 동작한다. 6 | 7 | # 뷰의 코드 형식 : 함수형, 클래스형 8 | # 함수형 : request를 매개변수로 받고(추가 매개변수 가능), 모양은 함수, 9 | # 내가 원하는대로 동작들을 설계하고 만들고 싶을 때 10 | 11 | # 클래스형 : CRUD 기존에 많이 사용하는 기능을 미리 클래스로 만들어두고 12 | # 상속받아서 사용한다. 13 | # 장고의 제네릭 뷰를 많이 사용 14 | from django.http import HttpResponse 15 | from django.shortcuts import render 16 | def index(request): 17 | # 어떤 계산이나, 데이터베이스 조회, 수정, 등록 18 | # 응답 메시지를 만들어서 반환. 19 | # html 변수를 대신해서 템플릿 20 | html = "Hi Django." 21 | return HttpResponse(html) 22 | 23 | # 뷰의 이름은 : welcome 24 | # 뷰의 접속 주소 : welcome/ 25 | # 내용은 : Welcome to Django. 26 | 27 | def welcome(request): 28 | html = "Welcome to Django." 29 | return HttpResponse(html) 30 | 31 | def template_test(request): 32 | # 기본 템플릿 폴더 33 | # 1. admin 앱 34 | # 2. 각 앱의 폴더에 있는 templates 폴더 35 | # 3. 여러분이 설정한 폴더 36 | return render(request, 'test.html') 37 | 38 | # 함수형 뷰 만들기, 템플릿 만들기, URL연결하기, 브라우저로 접속해보기 39 | -------------------------------------------------------------------------------- /django_basic/config/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for config project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /django_basic/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /django_basic/templates/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 이것은 템플릿 연습 파일입니다. 9 | 10 | --------------------------------------------------------------------------------