├── Chapter01 └── mysite │ ├── blog │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-37.pyc │ │ ├── admin.cpython-37.pyc │ │ ├── apps.cpython-37.pyc │ │ ├── models.cpython-37.pyc │ │ ├── urls.cpython-37.pyc │ │ └── views.cpython-37.pyc │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── __init__.py │ │ └── __pycache__ │ │ │ ├── 0001_initial.cpython-37.pyc │ │ │ └── __init__.cpython-37.pyc │ ├── models.py │ ├── static │ │ └── css │ │ │ └── blog.css │ ├── templates │ │ ├── blog │ │ │ ├── base.html │ │ │ └── post │ │ │ │ ├── detail.html │ │ │ │ └── list.html │ │ └── pagination.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── manage.py │ └── mysite │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-37.pyc │ ├── settings.cpython-37.pyc │ ├── urls.cpython-37.pyc │ └── wsgi.cpython-37.pyc │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── Chapter02 └── mysite │ ├── blog │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_comment.py │ │ ├── 0003_post_tags.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── css │ │ │ └── blog.css │ ├── templates │ │ ├── blog │ │ │ ├── base.html │ │ │ └── post │ │ │ │ ├── detail.html │ │ │ │ ├── list.html │ │ │ │ └── share.html │ │ └── pagination.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── manage.py │ └── mysite │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── Chapter03 └── mysite │ ├── blog │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── feeds.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_comment.py │ │ ├── 0003_post_tags.py │ │ └── __init__.py │ ├── models.py │ ├── sitemaps.py │ ├── static │ │ └── css │ │ │ └── blog.css │ ├── templates │ │ ├── blog │ │ │ ├── base.html │ │ │ └── post │ │ │ │ ├── detail.html │ │ │ │ ├── latest_posts.html │ │ │ │ ├── list.html │ │ │ │ ├── search.html │ │ │ │ └── share.html │ │ └── pagination.html │ ├── templatetags │ │ ├── __init__.py │ │ └── blog_tags.py │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── manage.py │ └── mysite │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── Chapter04 └── bookmarks │ ├── account │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── authentication.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── css │ │ │ └── base.css │ ├── templates │ │ ├── account │ │ │ ├── dashboard.html │ │ │ ├── edit.html │ │ │ ├── login.html │ │ │ ├── register.html │ │ │ └── register_done.html │ │ ├── base.html │ │ └── registration │ │ │ ├── logged_out.html │ │ │ ├── login.html │ │ │ ├── password_change_done.html │ │ │ ├── password_change_form.html │ │ │ ├── password_reset_complete.html │ │ │ ├── password_reset_confirm.html │ │ │ ├── password_reset_done.html │ │ │ ├── password_reset_email.html │ │ │ └── password_reset_form.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── bookmarks │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ └── manage.py ├── Chapter05 └── bookmarks │ ├── account │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── authentication.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── css │ │ │ └── base.css │ ├── templates │ │ ├── account │ │ │ ├── dashboard.html │ │ │ ├── edit.html │ │ │ ├── login.html │ │ │ ├── register.html │ │ │ └── register_done.html │ │ ├── base.html │ │ └── registration │ │ │ ├── logged_out.html │ │ │ ├── login.html │ │ │ ├── password_change_done.html │ │ │ ├── password_change_form.html │ │ │ ├── password_reset_complete.html │ │ │ ├── password_reset_confirm.html │ │ │ ├── password_reset_done.html │ │ │ ├── password_reset_email.html │ │ │ └── password_reset_form.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── bookmarks │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── common │ ├── __init__.py │ └── decorators.py │ ├── images │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ ├── css │ │ │ └── bookmarklet.css │ │ └── js │ │ │ └── bookmarklet.js │ ├── templates │ │ ├── bookmarklet_launcher.js │ │ └── images │ │ │ └── image │ │ │ ├── create.html │ │ │ ├── detail.html │ │ │ ├── list.html │ │ │ └── list_ajax.html │ ├── tests.py │ ├── urls.py │ └── views.py │ └── manage.py ├── Chapter06 └── bookmarks │ ├── account │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── authentication.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_contact.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── css │ │ │ └── base.css │ ├── templates │ │ ├── account │ │ │ ├── dashboard.html │ │ │ ├── edit.html │ │ │ ├── login.html │ │ │ ├── register.html │ │ │ ├── register_done.html │ │ │ └── user │ │ │ │ ├── detail.html │ │ │ │ └── list.html │ │ ├── base.html │ │ └── registration │ │ │ ├── logged_out.html │ │ │ ├── login.html │ │ │ ├── password_change_done.html │ │ │ ├── password_change_form.html │ │ │ ├── password_reset_complete.html │ │ │ ├── password_reset_confirm.html │ │ │ ├── password_reset_done.html │ │ │ ├── password_reset_email.html │ │ │ └── password_reset_form.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── actions │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── actions │ │ │ └── action │ │ │ └── detail.html │ ├── tests.py │ ├── utils.py │ └── views.py │ ├── bookmarks │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── common │ ├── __init__.py │ └── decorators.py │ ├── images │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_image_total_likes.py │ │ └── __init__.py │ ├── models.py │ ├── signals.py │ ├── static │ │ ├── css │ │ │ └── bookmarklet.css │ │ └── js │ │ │ └── bookmarklet.js │ ├── templates │ │ ├── bookmarklet_launcher.js │ │ └── images │ │ │ └── image │ │ │ ├── create.html │ │ │ ├── detail.html │ │ │ ├── list.html │ │ │ ├── list_ajax.html │ │ │ └── ranking.html │ ├── tests.py │ ├── urls.py │ └── views.py │ └── manage.py ├── Chapter07 └── myshop │ ├── 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 │ ├── manage.py │ ├── myshop │ ├── __init__.py │ ├── asgi.py │ ├── celery.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── orders │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── tasks.py │ ├── templates │ │ └── orders │ │ │ └── order │ │ │ ├── create.html │ │ │ └── created.html │ ├── tests.py │ ├── urls.py │ └── views.py │ └── shop │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ ├── 0001_initial.py │ └── __init__.py │ ├── models.py │ ├── static │ ├── css │ │ ├── base.css │ │ └── pdf.css │ └── img │ │ └── no_image.png │ ├── templates │ └── shop │ │ ├── base.html │ │ └── product │ │ ├── detail.html │ │ └── list.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── Chapter08 └── myshop │ ├── 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 │ ├── manage.py │ ├── myshop │ ├── __init__.py │ ├── asgi.py │ ├── celery.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── orders │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_order_braintree_id.py │ │ └── __init__.py │ ├── models.py │ ├── tasks.py │ ├── templates │ │ ├── admin │ │ │ └── orders │ │ │ │ └── order │ │ │ │ └── detail.html │ │ └── orders │ │ │ └── order │ │ │ ├── create.html │ │ │ ├── created.html │ │ │ └── pdf.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── payment │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tasks.py │ ├── templates │ │ └── payment │ │ │ ├── canceled.html │ │ │ ├── done.html │ │ │ └── process.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── shop │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ ├── css │ │ │ ├── base.css │ │ │ └── pdf.css │ │ └── img │ │ │ └── no_image.png │ ├── templates │ │ └── shop │ │ │ ├── base.html │ │ │ └── product │ │ │ ├── detail.html │ │ │ └── list.html │ ├── tests.py │ ├── urls.py │ └── views.py │ └── static │ ├── 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 │ ├── css │ ├── base.css │ └── pdf.css │ └── img │ └── no_image.png ├── Chapter09 └── myshop │ ├── 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 │ ├── coupons │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── locale │ ├── en │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ └── es │ │ └── LC_MESSAGES │ │ ├── django.mo │ │ └── django.po │ ├── manage.py │ ├── myshop │ ├── __init__.py │ ├── asgi.py │ ├── celery.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── orders │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── locale │ │ ├── en │ │ │ └── LC_MESSAGES │ │ │ │ ├── django.mo │ │ │ │ └── django.po │ │ └── es │ │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_order_braintree_id.py │ │ ├── 0003_auto_20191213_1618.py │ │ └── __init__.py │ ├── models.py │ ├── tasks.py │ ├── templates │ │ ├── admin │ │ │ └── orders │ │ │ │ └── order │ │ │ │ └── detail.html │ │ └── orders │ │ │ └── order │ │ │ ├── create.html │ │ │ ├── created.html │ │ │ └── pdf.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── payment │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tasks.py │ ├── templates │ │ └── payment │ │ │ ├── canceled.html │ │ │ ├── done.html │ │ │ └── process.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── shop │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_translations.py │ │ └── __init__.py │ ├── models.py │ ├── recommender.py │ ├── static │ │ ├── css │ │ │ ├── base.css │ │ │ └── pdf.css │ │ └── img │ │ │ └── no_image.png │ ├── templates │ │ └── shop │ │ │ ├── base.html │ │ │ └── product │ │ │ ├── detail.html │ │ │ └── list.html │ ├── tests.py │ ├── urls.py │ └── views.py │ └── static │ ├── 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 │ ├── css │ ├── base.css │ └── pdf.css │ └── img │ └── no_image.png ├── Chapter10 └── educa │ ├── courses │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── fields.py │ ├── fixtures │ │ └── subjects.json │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_content_file_image_text_video.py │ │ ├── 0003_auto_20191214_1253.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── css │ │ │ └── base.css │ ├── templates │ │ ├── base.html │ │ ├── courses │ │ │ └── manage │ │ │ │ ├── content │ │ │ │ └── form.html │ │ │ │ ├── course │ │ │ │ ├── delete.html │ │ │ │ ├── form.html │ │ │ │ └── list.html │ │ │ │ └── module │ │ │ │ ├── content_list.html │ │ │ │ └── formset.html │ │ └── registration │ │ │ ├── logged_out.html │ │ │ └── login.html │ ├── templatetags │ │ ├── __init__.py │ │ └── course.py │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── educa │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ └── manage.py ├── Chapter11 └── educa │ ├── courses │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── fields.py │ ├── fixtures │ │ └── subjects.json │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_content_file_image_text_video.py │ │ ├── 0003_auto_20191214_1253.py │ │ ├── 0004_course_students.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── css │ │ │ └── base.css │ ├── templates │ │ ├── base.html │ │ ├── courses │ │ │ ├── content │ │ │ │ ├── file.html │ │ │ │ ├── image.html │ │ │ │ ├── text.html │ │ │ │ └── video.html │ │ │ ├── course │ │ │ │ ├── detail.html │ │ │ │ └── list.html │ │ │ └── manage │ │ │ │ ├── content │ │ │ │ └── form.html │ │ │ │ ├── course │ │ │ │ ├── delete.html │ │ │ │ ├── form.html │ │ │ │ └── list.html │ │ │ │ └── module │ │ │ │ ├── content_list.html │ │ │ │ └── formset.html │ │ └── registration │ │ │ ├── logged_out.html │ │ │ └── login.html │ ├── templatetags │ │ ├── __init__.py │ │ └── course.py │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── educa │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── manage.py │ └── students │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ └── __init__.py │ ├── models.py │ ├── templates │ └── students │ │ ├── course │ │ ├── detail.html │ │ └── list.html │ │ └── student │ │ └── registration.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── Chapter12 ├── api_examples │ └── enroll_all.py └── educa │ ├── courses │ ├── __init__.py │ ├── admin.py │ ├── api │ │ ├── __init__.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ ├── urls.py │ │ └── views.py │ ├── apps.py │ ├── fields.py │ ├── fixtures │ │ └── subjects.json │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_content_file_image_text_video.py │ │ ├── 0003_auto_20191214_1253.py │ │ ├── 0004_course_students.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── css │ │ │ └── base.css │ ├── templates │ │ ├── base.html │ │ ├── courses │ │ │ ├── content │ │ │ │ ├── file.html │ │ │ │ ├── image.html │ │ │ │ ├── text.html │ │ │ │ └── video.html │ │ │ ├── course │ │ │ │ ├── detail.html │ │ │ │ └── list.html │ │ │ └── manage │ │ │ │ ├── content │ │ │ │ └── form.html │ │ │ │ ├── course │ │ │ │ ├── delete.html │ │ │ │ ├── form.html │ │ │ │ └── list.html │ │ │ │ └── module │ │ │ │ ├── content_list.html │ │ │ │ └── formset.html │ │ └── registration │ │ │ ├── logged_out.html │ │ │ └── login.html │ ├── templatetags │ │ ├── __init__.py │ │ └── course.py │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── educa │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── manage.py │ └── students │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ └── __init__.py │ ├── models.py │ ├── templates │ └── students │ │ ├── course │ │ ├── detail.html │ │ └── list.html │ │ └── student │ │ └── registration.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── Chapter13 └── educa │ ├── chat │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── consumers.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── routing.py │ ├── templates │ │ └── chat │ │ │ └── room.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── courses │ ├── __init__.py │ ├── admin.py │ ├── api │ │ ├── __init__.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ ├── urls.py │ │ └── views.py │ ├── apps.py │ ├── fields.py │ ├── fixtures │ │ └── subjects.json │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_content_file_image_text_video.py │ │ ├── 0003_auto_20191214_1253.py │ │ ├── 0004_course_students.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── css │ │ │ └── base.css │ ├── templates │ │ ├── base.html │ │ ├── courses │ │ │ ├── content │ │ │ │ ├── file.html │ │ │ │ ├── image.html │ │ │ │ ├── text.html │ │ │ │ └── video.html │ │ │ ├── course │ │ │ │ ├── detail.html │ │ │ │ └── list.html │ │ │ └── manage │ │ │ │ ├── content │ │ │ │ └── form.html │ │ │ │ ├── course │ │ │ │ ├── delete.html │ │ │ │ ├── form.html │ │ │ │ └── list.html │ │ │ │ └── module │ │ │ │ ├── content_list.html │ │ │ │ └── formset.html │ │ └── registration │ │ │ ├── logged_out.html │ │ │ └── login.html │ ├── templatetags │ │ ├── __init__.py │ │ └── course.py │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── educa │ ├── __init__.py │ ├── asgi.py │ ├── routing.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── manage.py │ └── students │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ └── __init__.py │ ├── models.py │ ├── templates │ └── students │ │ ├── course │ │ ├── detail.html │ │ └── list.html │ │ └── student │ │ └── registration.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── Chapter14 └── educa │ ├── chat │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── consumers.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── routing.py │ ├── templates │ │ └── chat │ │ │ └── room.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── config │ ├── nginx.conf │ └── uwsgi.ini │ ├── courses │ ├── __init__.py │ ├── admin.py │ ├── api │ │ ├── __init__.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ ├── urls.py │ │ └── views.py │ ├── apps.py │ ├── fields.py │ ├── fixtures │ │ └── subjects.json │ ├── forms.py │ ├── middleware.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_content_file_image_text_video.py │ │ ├── 0003_auto_20191214_1253.py │ │ ├── 0004_course_students.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── css │ │ │ └── base.css │ ├── templates │ │ ├── base.html │ │ ├── courses │ │ │ ├── content │ │ │ │ ├── file.html │ │ │ │ ├── image.html │ │ │ │ ├── text.html │ │ │ │ └── video.html │ │ │ ├── course │ │ │ │ ├── detail.html │ │ │ │ └── list.html │ │ │ └── manage │ │ │ │ ├── content │ │ │ │ └── form.html │ │ │ │ ├── course │ │ │ │ ├── delete.html │ │ │ │ ├── form.html │ │ │ │ └── list.html │ │ │ │ └── module │ │ │ │ ├── content_list.html │ │ │ │ └── formset.html │ │ └── registration │ │ │ ├── logged_out.html │ │ │ └── login.html │ ├── templatetags │ │ ├── __init__.py │ │ └── course.py │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── educa │ ├── __init__.py │ ├── asgi.py │ ├── routing.py │ ├── settings │ │ ├── base.py │ │ ├── local.py │ │ └── pro.py │ ├── urls.py │ └── wsgi.py │ ├── logs │ └── nginx_error.log │ ├── manage.py │ ├── ssl │ ├── educa.crt │ └── educa.key │ ├── static │ ├── 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 │ ├── css │ │ └── base.css │ ├── memcache_status.css │ └── rest_framework │ │ ├── css │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap-tweaks.css │ │ ├── bootstrap.min.css │ │ ├── default.css │ │ ├── font-awesome-4.0.3.css │ │ └── prettify.css │ │ ├── docs │ │ ├── css │ │ │ ├── base.css │ │ │ ├── highlight.css │ │ │ └── jquery.json-view.min.css │ │ ├── img │ │ │ ├── favicon.ico │ │ │ └── grid.png │ │ └── js │ │ │ ├── api.js │ │ │ ├── highlight.pack.js │ │ │ └── jquery.json-view.min.js │ │ ├── fonts │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── img │ │ ├── glyphicons-halflings-white.png │ │ ├── glyphicons-halflings.png │ │ └── grid.png │ │ └── js │ │ ├── ajax-form.js │ │ ├── bootstrap.min.js │ │ ├── coreapi-0.1.1.js │ │ ├── csrf.js │ │ ├── default.js │ │ ├── jquery-3.4.1.min.js │ │ └── prettify-min.js │ └── students │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ └── enroll_reminder.py │ ├── migrations │ └── __init__.py │ ├── models.py │ ├── templates │ └── students │ │ ├── course │ │ ├── detail.html │ │ └── list.html │ │ └── student │ │ └── registration.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── LICENSE └── README.md /Chapter01/mysite/blog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/__init__.py -------------------------------------------------------------------------------- /Chapter01/mysite/blog/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/blog/__pycache__/admin.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/__pycache__/admin.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/blog/__pycache__/apps.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/__pycache__/apps.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/blog/__pycache__/models.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/__pycache__/models.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/blog/__pycache__/urls.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/__pycache__/urls.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/blog/__pycache__/views.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/__pycache__/views.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/blog/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Post 3 | 4 | @admin.register(Post) 5 | class PostAdmin(admin.ModelAdmin): 6 | list_display = ('title', 'slug', 'author', 'publish', 'status') 7 | list_filter = ('status', 'created', 'publish', 'author') 8 | search_fields = ('title', 'body') 9 | prepopulated_fields = {'slug': ('title',)} 10 | raw_id_fields = ('author',) 11 | date_hierarchy = 'publish' 12 | ordering = ('status', 'publish') 13 | -------------------------------------------------------------------------------- /Chapter01/mysite/blog/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BlogConfig(AppConfig): 5 | name = 'blog' 6 | -------------------------------------------------------------------------------- /Chapter01/mysite/blog/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter01/mysite/blog/migrations/__pycache__/0001_initial.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/migrations/__pycache__/0001_initial.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/blog/migrations/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/blog/migrations/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/blog/templates/blog/base.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | {% block title %}{% endblock %} 6 | 7 | 8 | 9 |
10 | {% block content %} 11 | {% endblock %} 12 |
13 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Chapter01/mysite/blog/templates/blog/post/detail.html: -------------------------------------------------------------------------------- 1 | {% extends "blog/base.html" %} 2 | 3 | {% block title %}{{ post.title }}{% endblock %} 4 | 5 | {% block content %} 6 |

{{ post.title }}

7 |

8 | Published {{ post.publish }} by {{ post.author }} 9 |

10 | {{ post.body|linebreaks }} 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter01/mysite/blog/templates/blog/post/list.html: -------------------------------------------------------------------------------- 1 | {% extends "blog/base.html" %} 2 | 3 | {% block title %}My Blog{% endblock %} 4 | 5 | {% block content %} 6 |

My Blog

7 | {% for post in posts %} 8 |

9 | 10 | {{ post.title }} 11 | 12 |

13 |

14 | Published {{ post.publish }} by {{ post.author }} 15 |

16 | {{ post.body|truncatewords:30|linebreaks }} 17 | {% endfor %} 18 | {% include "pagination.html" with page=page_obj %} 19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /Chapter01/mysite/blog/templates/pagination.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /Chapter01/mysite/blog/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter01/mysite/blog/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'blog' 5 | 6 | urlpatterns = [ 7 | # post views 8 | # path('', views.post_list, name='post_list'), 9 | path('', views.PostListView.as_view(), name='post_list'), 10 | path('////', 11 | views.post_detail, 12 | name='post_detail'), 13 | ] 14 | -------------------------------------------------------------------------------- /Chapter01/mysite/mysite/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/mysite/__init__.py -------------------------------------------------------------------------------- /Chapter01/mysite/mysite/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/mysite/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/mysite/__pycache__/settings.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/mysite/__pycache__/settings.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/mysite/__pycache__/urls.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/mysite/__pycache__/urls.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/mysite/__pycache__/wsgi.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter01/mysite/mysite/__pycache__/wsgi.cpython-37.pyc -------------------------------------------------------------------------------- /Chapter01/mysite/mysite/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for mysite 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', 'mysite.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter01/mysite/mysite/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mysite 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', 'mysite.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter02/mysite/blog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter02/mysite/blog/__init__.py -------------------------------------------------------------------------------- /Chapter02/mysite/blog/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BlogConfig(AppConfig): 5 | name = 'blog' 6 | -------------------------------------------------------------------------------- /Chapter02/mysite/blog/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from .models import Comment 3 | 4 | 5 | class EmailPostForm(forms.Form): 6 | name = forms.CharField(max_length=25) 7 | email = forms.EmailField() 8 | to = forms.EmailField() 9 | comments = forms.CharField(required=False, 10 | widget=forms.Textarea) 11 | 12 | 13 | class CommentForm(forms.ModelForm): 14 | class Meta: 15 | model = Comment 16 | fields = ('name', 'email', 'body') 17 | -------------------------------------------------------------------------------- /Chapter02/mysite/blog/migrations/0003_post_tags.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0 on 2019-10-30 13:15 2 | 3 | from django.db import migrations 4 | import taggit.managers 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('taggit', '0003_taggeditem_add_unique_index'), 11 | ('blog', '0002_comment'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='post', 17 | name='tags', 18 | field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /Chapter02/mysite/blog/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter02/mysite/blog/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter02/mysite/blog/templates/blog/base.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | {% block title %}{% endblock %} 6 | 7 | 8 | 9 |
10 | {% block content %} 11 | {% endblock %} 12 |
13 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Chapter02/mysite/blog/templates/blog/post/share.html: -------------------------------------------------------------------------------- 1 | {% extends "blog/base.html" %} 2 | 3 | {% block title %}Share a post{% endblock %} 4 | 5 | {% block content %} 6 | {% if sent %} 7 |

E-mail successfully sent

8 |

9 | "{{ post.title }}" was successfully sent to {{ form.cleaned_data.to }}. 10 |

11 | {% else %} 12 |

Share "{{ post.title }}" by e-mail

13 |
14 | {{ form.as_p }} 15 | {% csrf_token %} 16 | 17 |
18 | {% endif %} 19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /Chapter02/mysite/blog/templates/pagination.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /Chapter02/mysite/blog/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter02/mysite/blog/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'blog' 5 | 6 | urlpatterns = [ 7 | # post views 8 | path('', views.post_list, name='post_list'), 9 | path('tag//', views.post_list, name='post_list_by_tag'), 10 | # path('', views.PostListView.as_view(), name='post_list'), 11 | path('////', views.post_detail, name='post_detail'), 12 | path('/share/', views.post_share, name='post_share'), 13 | 14 | ] 15 | -------------------------------------------------------------------------------- /Chapter02/mysite/mysite/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter02/mysite/mysite/__init__.py -------------------------------------------------------------------------------- /Chapter02/mysite/mysite/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for mysite 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', 'mysite.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter02/mysite/mysite/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mysite 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', 'mysite.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter03/mysite/blog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter03/mysite/blog/__init__.py -------------------------------------------------------------------------------- /Chapter03/mysite/blog/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BlogConfig(AppConfig): 5 | name = 'blog' 6 | -------------------------------------------------------------------------------- /Chapter03/mysite/blog/feeds.py: -------------------------------------------------------------------------------- 1 | from django.contrib.syndication.views import Feed 2 | from django.template.defaultfilters import truncatewords 3 | from django.urls import reverse_lazy 4 | from .models import Post 5 | 6 | 7 | class LatestPostsFeed(Feed): 8 | title = 'My blog' 9 | link = reverse_lazy('blog:post_list') 10 | description = 'New posts of my blog.' 11 | 12 | def items(self): 13 | return Post.published.all()[:5] 14 | 15 | def item_title(self, item): 16 | return item.title 17 | 18 | def item_description(self, item): 19 | return truncatewords(item.body, 30) 20 | -------------------------------------------------------------------------------- /Chapter03/mysite/blog/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from .models import Comment 3 | 4 | 5 | class EmailPostForm(forms.Form): 6 | name = forms.CharField(max_length=25) 7 | email = forms.EmailField() 8 | to = forms.EmailField() 9 | comments = forms.CharField(required=False, 10 | widget=forms.Textarea) 11 | 12 | 13 | class CommentForm(forms.ModelForm): 14 | class Meta: 15 | model = Comment 16 | fields = ('name', 'email', 'body') 17 | 18 | 19 | class SearchForm(forms.Form): 20 | query = forms.CharField() 21 | -------------------------------------------------------------------------------- /Chapter03/mysite/blog/migrations/0003_post_tags.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0 on 2019-10-30 13:15 2 | 3 | from django.db import migrations 4 | import taggit.managers 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('taggit', '0003_taggeditem_add_unique_index'), 11 | ('blog', '0002_comment'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='post', 17 | name='tags', 18 | field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /Chapter03/mysite/blog/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter03/mysite/blog/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter03/mysite/blog/sitemaps.py: -------------------------------------------------------------------------------- 1 | from django.contrib.sitemaps import Sitemap 2 | from .models import Post 3 | 4 | 5 | class PostSitemap(Sitemap): 6 | changefreq = 'weekly' 7 | priority = 0.9 8 | 9 | def items(self): 10 | return Post.published.all() 11 | 12 | def lastmod(self, obj): 13 | return obj.updated 14 | -------------------------------------------------------------------------------- /Chapter03/mysite/blog/templates/blog/post/latest_posts.html: -------------------------------------------------------------------------------- 1 |
    2 | {% for post in latest_posts %} 3 |
  • 4 | {{ post.title }} 5 |
  • 6 | {% endfor %} 7 |
8 | -------------------------------------------------------------------------------- /Chapter03/mysite/blog/templates/blog/post/share.html: -------------------------------------------------------------------------------- 1 | {% extends "blog/base.html" %} 2 | 3 | {% block title %}Share a post{% endblock %} 4 | 5 | {% block content %} 6 | {% if sent %} 7 |

E-mail successfully sent

8 |

9 | "{{ post.title }}" was successfully sent to {{ form.cleaned_data.to }}. 10 |

11 | {% else %} 12 |

Share "{{ post.title }}" by e-mail

13 |
14 | {{ form.as_p }} 15 | {% csrf_token %} 16 | 17 |
18 | {% endif %} 19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /Chapter03/mysite/blog/templates/pagination.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /Chapter03/mysite/blog/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter03/mysite/blog/templatetags/__init__.py -------------------------------------------------------------------------------- /Chapter03/mysite/blog/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter03/mysite/mysite/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter03/mysite/mysite/__init__.py -------------------------------------------------------------------------------- /Chapter03/mysite/mysite/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for mysite 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', 'mysite.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter03/mysite/mysite/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mysite 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', 'mysite.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter04/bookmarks/account/__init__.py -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Profile 3 | 4 | 5 | @admin.register(Profile) 6 | class ProfileAdmin(admin.ModelAdmin): 7 | list_display = ['user', 'date_of_birth', 'photo'] 8 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AccountConfig(AppConfig): 5 | name = 'account' 6 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter04/bookmarks/account/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.conf import settings 3 | 4 | 5 | class Profile(models.Model): 6 | user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 7 | date_of_birth = models.DateField(blank=True, null=True) 8 | photo = models.ImageField(upload_to='users/%Y/%m/%d/', blank=True) 9 | 10 | def __str__(self): 11 | return f'Profile for user {self.user.username}' 12 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/account/dashboard.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Dashboard{% endblock %} 4 | 5 | {% block content %} 6 |

Dashboard

7 |

Welcome to your dashboard. You can edit your profile or change your password.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/account/edit.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Edit your account{% endblock %} 4 | 5 | {% block content %} 6 |

Edit your account

7 |

You can edit your account using the following form:

8 |
9 | {{ user_form.as_p }} 10 | {{ profile_form.as_p }} 11 | {% csrf_token %} 12 |

13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/account/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Log-in{% endblock %} 4 | 5 | {% block content %} 6 |

Log-in

7 |

Please, use the following form to log-in:

8 |
9 | {{ form.as_p }} 10 | {% csrf_token %} 11 |

12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/account/register.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Create an account{% endblock %} 4 | 5 | {% block content %} 6 |

Create an account

7 |

Please, sign up using the following form:

8 |
9 | {{ user_form.as_p }} 10 | {% csrf_token %} 11 |

12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/account/register_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Welcome{% endblock %} 4 | 5 | {% block content %} 6 |

Welcome {{ new_user.first_name }}!

7 |

Your account has been successfully created. Now you can log in.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/registration/logged_out.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Logged out{% endblock %} 4 | 5 | {% block content %} 6 |

Logged out

7 |

8 | You have been successfully logged out. 9 | You can log-in again. 10 |

11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/registration/password_change_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Password changed{% endblock %} 4 | 5 | {% block content %} 6 |

Password changed

7 |

Your password has been successfully changed.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/registration/password_change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Change your password{% endblock %} 4 | 5 | {% block content %} 6 |

Change your password

7 |

Use the form below to change your password.

8 |
9 | {{ form.as_p }} 10 |

11 | {% csrf_token %} 12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/registration/password_reset_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Password reset{% endblock %} 4 | 5 | {% block content %} 6 |

Password set

7 |

Your password has been set. You can log in now

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/registration/password_reset_confirm.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Reset your password{% endblock %} 4 | 5 | {% block content %} 6 |

Reset your password

7 | {% if validlink %} 8 |

Please enter your new password twice:

9 |
10 | {{ form.as_p }} 11 | {% csrf_token %} 12 |

13 |
14 | {% else %} 15 |

The password reset link was invalid, possibly because it has 16 | already been used. Please request a new password reset.

17 | {% endif %} 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/registration/password_reset_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Reset your password{% endblock %} 4 | 5 | {% block content %} 6 |

Reset your password

7 |

We've emailed you instructions for setting your password.

8 |

If you don't receive an email, please make sure you've entered the address you registered with.

9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/registration/password_reset_email.html: -------------------------------------------------------------------------------- 1 | Someone asked for password reset for email {{ email }}. Follow the link below: 2 | {{ protocol }}://{{ domain }}{% url "password_reset_confirm" uidb64=uid token=token %} 3 | Your username, in case you've forgotten: {{ user.get_username }} 4 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/templates/registration/password_reset_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Reset your password{% endblock %} 4 | 5 | {% block content %} 6 |

Forgotten your password?

7 |

Enter your e-mail address to obtain a new password.

8 |
9 | {{ form.as_p }} 10 |

11 | {% csrf_token %} 12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/account/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/bookmarks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter04/bookmarks/bookmarks/__init__.py -------------------------------------------------------------------------------- /Chapter04/bookmarks/bookmarks/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for bookmarks 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', 'bookmarks.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/bookmarks/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, include 2 | from django.contrib import admin 3 | from django.conf import settings 4 | from django.conf.urls.static import static 5 | 6 | urlpatterns = [ 7 | path('admin/', admin.site.urls), 8 | path('account/', include('account.urls')), 9 | path('social-auth/', include('social_django.urls', namespace='social')), 10 | ] 11 | 12 | if settings.DEBUG: 13 | urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 14 | -------------------------------------------------------------------------------- /Chapter04/bookmarks/bookmarks/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for bookmarks 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', 'bookmarks.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter05/bookmarks/account/__init__.py -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Profile 3 | 4 | 5 | @admin.register(Profile) 6 | class ProfileAdmin(admin.ModelAdmin): 7 | list_display = ['user', 'date_of_birth', 'photo'] 8 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AccountConfig(AppConfig): 5 | name = 'account' 6 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter05/bookmarks/account/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.conf import settings 3 | 4 | 5 | class Profile(models.Model): 6 | user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 7 | date_of_birth = models.DateField(blank=True, null=True) 8 | photo = models.ImageField(upload_to='users/%Y/%m/%d/', blank=True) 9 | 10 | def __str__(self): 11 | return f'Profile for user {self.user.username}' 12 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/account/edit.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Edit your account{% endblock %} 4 | 5 | {% block content %} 6 |

Edit your account

7 |

You can edit your account using the following form:

8 |
9 | {{ user_form.as_p }} 10 | {{ profile_form.as_p }} 11 | {% csrf_token %} 12 |

13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/account/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Log-in{% endblock %} 4 | 5 | {% block content %} 6 |

Log-in

7 |

Please, use the following form to log-in:

8 |
9 | {{ form.as_p }} 10 | {% csrf_token %} 11 |

12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/account/register.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Create an account{% endblock %} 4 | 5 | {% block content %} 6 |

Create an account

7 |

Please, sign up using the following form:

8 |
9 | {{ user_form.as_p }} 10 | {% csrf_token %} 11 |

12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/account/register_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Welcome{% endblock %} 4 | 5 | {% block content %} 6 |

Welcome {{ new_user.first_name }}!

7 |

Your account has been successfully created. Now you can log in.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/registration/logged_out.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Logged out{% endblock %} 4 | 5 | {% block content %} 6 |

Logged out

7 |

8 | You have been successfully logged out. 9 | You can log-in again. 10 |

11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/registration/password_change_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Password changed{% endblock %} 4 | 5 | {% block content %} 6 |

Password changed

7 |

Your password has been successfully changed.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/registration/password_change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Change your password{% endblock %} 4 | 5 | {% block content %} 6 |

Change your password

7 |

Use the form below to change your password.

8 |
9 | {{ form.as_p }} 10 |

11 | {% csrf_token %} 12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/registration/password_reset_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Password reset{% endblock %} 4 | 5 | {% block content %} 6 |

Password set

7 |

Your password has been set. You can log in now

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/registration/password_reset_confirm.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Reset your password{% endblock %} 4 | 5 | {% block content %} 6 |

Reset your password

7 | {% if validlink %} 8 |

Please enter your new password twice:

9 |
10 | {{ form.as_p }} 11 | {% csrf_token %} 12 |

13 |
14 | {% else %} 15 |

The password reset link was invalid, possibly because it has 16 | already been used. Please request a new password reset.

17 | {% endif %} 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/registration/password_reset_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Reset your password{% endblock %} 4 | 5 | {% block content %} 6 |

Reset your password

7 |

We've emailed you instructions for setting your password.

8 |

If you don't receive an email, please make sure you've entered the address you registered with.

9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/registration/password_reset_email.html: -------------------------------------------------------------------------------- 1 | Someone asked for password reset for email {{ email }}. Follow the link below: 2 | {{ protocol }}://{{ domain }}{% url "password_reset_confirm" uidb64=uid token=token %} 3 | Your username, in case you've forgotten: {{ user.get_username }} 4 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/templates/registration/password_reset_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Reset your password{% endblock %} 4 | 5 | {% block content %} 6 |

Forgotten your password?

7 |

Enter your e-mail address to obtain a new password.

8 |
9 | {{ form.as_p }} 10 |

11 | {% csrf_token %} 12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/account/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/bookmarks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter05/bookmarks/bookmarks/__init__.py -------------------------------------------------------------------------------- /Chapter05/bookmarks/bookmarks/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for bookmarks 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', 'bookmarks.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/bookmarks/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, include 2 | from django.contrib import admin 3 | from django.conf import settings 4 | from django.conf.urls.static import static 5 | 6 | urlpatterns = [ 7 | path('admin/', admin.site.urls), 8 | path('account/', include('account.urls')), 9 | path('social-auth/', include('social_django.urls', namespace='social')), 10 | path('images/', include('images.urls', namespace='images')), 11 | ] 12 | 13 | if settings.DEBUG: 14 | urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 15 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/bookmarks/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for bookmarks 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', 'bookmarks.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter05/bookmarks/common/__init__.py -------------------------------------------------------------------------------- /Chapter05/bookmarks/common/decorators.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponseBadRequest 2 | 3 | 4 | def ajax_required(f): 5 | def wrap(request, *args, **kwargs): 6 | if not request.is_ajax(): 7 | return HttpResponseBadRequest() 8 | return f(request, *args, **kwargs) 9 | wrap.__doc__=f.__doc__ 10 | wrap.__name__=f.__name__ 11 | return wrap 12 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/images/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter05/bookmarks/images/__init__.py -------------------------------------------------------------------------------- /Chapter05/bookmarks/images/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Image 3 | 4 | 5 | @admin.register(Image) 6 | class ImageAdmin(admin.ModelAdmin): 7 | list_display = ['title', 'slug', 'image', 'created'] 8 | list_filter = ['created'] 9 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/images/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ImagesConfig(AppConfig): 5 | name = 'images' 6 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/images/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter05/bookmarks/images/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter05/bookmarks/images/templates/bookmarklet_launcher.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | if (window.myBookmarklet !== undefined){ 3 | myBookmarklet(); 4 | } 5 | else { 6 | document.body.appendChild(document.createElement('script')).src='https://127.0.0.1:8000/static/js/bookmarklet.js?r='+Math.floor(Math.random()*99999999999999999999); 7 | } 8 | })(); 9 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/images/templates/images/image/create.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Bookmark an image{% endblock %} 4 | 5 | {% block content %} 6 |

Bookmark an image

7 | 8 |
9 | {{ form.as_p }} 10 | {% csrf_token %} 11 | 12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/images/templates/images/image/list_ajax.html: -------------------------------------------------------------------------------- 1 | {% load thumbnail %} 2 | 3 | {% for image in images %} 4 | 17 | {% endfor %} 18 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/images/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter05/bookmarks/images/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'images' 5 | 6 | urlpatterns = [ 7 | path('create/', views.image_create, name='create'), 8 | path('detail///', views.image_detail, name='detail'), 9 | path('like/', views.image_like, name='like'), 10 | path('', views.image_list, name='list'), 11 | ] 12 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter06/bookmarks/account/__init__.py -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Profile 3 | 4 | 5 | @admin.register(Profile) 6 | class ProfileAdmin(admin.ModelAdmin): 7 | list_display = ['user', 'date_of_birth', 'photo'] 8 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AccountConfig(AppConfig): 5 | name = 'account' 6 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter06/bookmarks/account/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/account/edit.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Edit your account{% endblock %} 4 | 5 | {% block content %} 6 |

Edit your account

7 |

You can edit your account using the following form:

8 |
9 | {{ user_form.as_p }} 10 | {{ profile_form.as_p }} 11 | {% csrf_token %} 12 |

13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/account/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Log-in{% endblock %} 4 | 5 | {% block content %} 6 |

Log-in

7 |

Please, use the following form to log-in:

8 |
9 | {{ form.as_p }} 10 | {% csrf_token %} 11 |

12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/account/register.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Create an account{% endblock %} 4 | 5 | {% block content %} 6 |

Create an account

7 |

Please, sign up using the following form:

8 |
9 | {{ user_form.as_p }} 10 | {% csrf_token %} 11 |

12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/account/register_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Welcome{% endblock %} 4 | 5 | {% block content %} 6 |

Welcome {{ new_user.first_name }}!

7 |

Your account has been successfully created. Now you can log in.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/registration/logged_out.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Logged out{% endblock %} 4 | 5 | {% block content %} 6 |

Logged out

7 |

8 | You have been successfully logged out. 9 | You can log-in again. 10 |

11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/registration/password_change_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Password changed{% endblock %} 4 | 5 | {% block content %} 6 |

Password changed

7 |

Your password has been successfully changed.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/registration/password_change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Change your password{% endblock %} 4 | 5 | {% block content %} 6 |

Change your password

7 |

Use the form below to change your password.

8 |
9 | {{ form.as_p }} 10 |

11 | {% csrf_token %} 12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/registration/password_reset_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Password reset{% endblock %} 4 | 5 | {% block content %} 6 |

Password set

7 |

Your password has been set. You can log in now

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/registration/password_reset_confirm.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Reset your password{% endblock %} 4 | 5 | {% block content %} 6 |

Reset your password

7 | {% if validlink %} 8 |

Please enter your new password twice:

9 |
10 | {{ form.as_p }} 11 | {% csrf_token %} 12 |

13 |
14 | {% else %} 15 |

The password reset link was invalid, possibly because it has 16 | already been used. Please request a new password reset.

17 | {% endif %} 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/registration/password_reset_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Reset your password{% endblock %} 4 | 5 | {% block content %} 6 |

Reset your password

7 |

We've emailed you instructions for setting your password.

8 |

If you don't receive an email, please make sure you've entered the address you registered with.

9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/registration/password_reset_email.html: -------------------------------------------------------------------------------- 1 | Someone asked for password reset for email {{ email }}. Follow the link below: 2 | {{ protocol }}://{{ domain }}{% url "password_reset_confirm" uidb64=uid token=token %} 3 | Your username, in case you've forgotten: {{ user.get_username }} 4 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/templates/registration/password_reset_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Reset your password{% endblock %} 4 | 5 | {% block content %} 6 |

Forgotten your password?

7 |

Enter your e-mail address to obtain a new password.

8 |
9 | {{ form.as_p }} 10 |

11 | {% csrf_token %} 12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/account/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/actions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter06/bookmarks/actions/__init__.py -------------------------------------------------------------------------------- /Chapter06/bookmarks/actions/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Action 3 | 4 | 5 | @admin.register(Action) 6 | class ActionAdmin(admin.ModelAdmin): 7 | list_display = ('user', 'verb', 'target', 'created') 8 | list_filter = ('created',) 9 | search_fields = ('verb',) 10 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/actions/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ActionsConfig(AppConfig): 5 | name = 'actions' 6 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/actions/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter06/bookmarks/actions/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter06/bookmarks/actions/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/actions/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/bookmarks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter06/bookmarks/bookmarks/__init__.py -------------------------------------------------------------------------------- /Chapter06/bookmarks/bookmarks/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for bookmarks 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', 'bookmarks.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/bookmarks/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, include 2 | from django.contrib import admin 3 | from django.conf import settings 4 | from django.conf.urls.static import static 5 | 6 | urlpatterns = [ 7 | path('admin/', admin.site.urls), 8 | path('account/', include('account.urls')), 9 | path('social-auth/', include('social_django.urls', namespace='social')), 10 | path('images/', include('images.urls', namespace='images')), 11 | ] 12 | 13 | if settings.DEBUG: 14 | urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 15 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/bookmarks/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for bookmarks 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', 'bookmarks.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter06/bookmarks/common/__init__.py -------------------------------------------------------------------------------- /Chapter06/bookmarks/common/decorators.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponseBadRequest 2 | 3 | 4 | def ajax_required(f): 5 | def wrap(request, *args, **kwargs): 6 | if not request.is_ajax(): 7 | return HttpResponseBadRequest() 8 | return f(request, *args, **kwargs) 9 | wrap.__doc__=f.__doc__ 10 | wrap.__name__=f.__name__ 11 | return wrap 12 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter06/bookmarks/images/__init__.py -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Image 3 | 4 | 5 | @admin.register(Image) 6 | class ImageAdmin(admin.ModelAdmin): 7 | list_display = ['title', 'slug', 'image', 'created'] 8 | list_filter = ['created'] 9 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ImagesConfig(AppConfig): 5 | name = 'images' 6 | 7 | def ready(self): 8 | # import signal handlers 9 | import images.signals 10 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/migrations/0002_image_total_likes.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0 on 2019-11-29 09:11 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('images', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='image', 15 | name='total_likes', 16 | field=models.PositiveIntegerField(db_index=True, default=0), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter06/bookmarks/images/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/signals.py: -------------------------------------------------------------------------------- 1 | from django.db.models.signals import m2m_changed 2 | from django.dispatch import receiver 3 | from .models import Image 4 | 5 | 6 | @receiver(m2m_changed, sender=Image.users_like.through) 7 | def users_like_changed(sender, instance, **kwargs): 8 | instance.total_likes = instance.users_like.count() 9 | instance.save() 10 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/templates/bookmarklet_launcher.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | if (window.myBookmarklet !== undefined){ 3 | myBookmarklet(); 4 | } 5 | else { 6 | document.body.appendChild(document.createElement('script')).src='https://127.0.0.1:8000/static/js/bookmarklet.js?r='+Math.floor(Math.random()*99999999999999999999); 7 | } 8 | })(); 9 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/templates/images/image/create.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Bookmark an image{% endblock %} 4 | 5 | {% block content %} 6 |

Bookmark an image

7 | 8 |
9 | {{ form.as_p }} 10 | {% csrf_token %} 11 | 12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/templates/images/image/list_ajax.html: -------------------------------------------------------------------------------- 1 | {% load thumbnail %} 2 | 3 | {% for image in images %} 4 | 17 | {% endfor %} 18 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/templates/images/image/ranking.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Images ranking{% endblock %} 4 | 5 | {% block content %} 6 |

Images ranking

7 |
    8 | {% for image in most_viewed %} 9 |
  1. 10 | 11 | {{ image.title }} 12 | 13 |
  2. 14 | {% endfor %} 15 |
16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter06/bookmarks/images/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'images' 5 | 6 | urlpatterns = [ 7 | path('create/', views.image_create, name='create'), 8 | path('detail///', views.image_detail, name='detail'), 9 | path('like/', views.image_like, name='like'), 10 | path('', views.image_list, name='list'), 11 | path('ranking/', views.image_ranking, name='ranking'), 12 | ] 13 | -------------------------------------------------------------------------------- /Chapter07/myshop/cart/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter07/myshop/cart/__init__.py -------------------------------------------------------------------------------- /Chapter07/myshop/cart/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Chapter07/myshop/cart/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CartConfig(AppConfig): 5 | name = 'cart' 6 | -------------------------------------------------------------------------------- /Chapter07/myshop/cart/context_processors.py: -------------------------------------------------------------------------------- 1 | from .cart import Cart 2 | 3 | 4 | def cart(request): 5 | return {'cart': Cart(request)} 6 | -------------------------------------------------------------------------------- /Chapter07/myshop/cart/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | 4 | PRODUCT_QUANTITY_CHOICES = [(i, str(i)) for i in range(1, 21)] 5 | 6 | 7 | class CartAddProductForm(forms.Form): 8 | quantity = forms.TypedChoiceField( 9 | choices=PRODUCT_QUANTITY_CHOICES, 10 | coerce=int) 11 | override = forms.BooleanField(required=False, 12 | initial=False, 13 | widget=forms.HiddenInput) 14 | -------------------------------------------------------------------------------- /Chapter07/myshop/cart/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter07/myshop/cart/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter07/myshop/cart/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Chapter07/myshop/cart/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter07/myshop/cart/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'cart' 5 | 6 | urlpatterns = [ 7 | path('', views.cart_detail, name='cart_detail'), 8 | path('add//', views.cart_add, name='cart_add'), 9 | path('remove//', views.cart_remove, name='cart_remove'), 10 | ] 11 | -------------------------------------------------------------------------------- /Chapter07/myshop/myshop/__init__.py: -------------------------------------------------------------------------------- 1 | # import celery 2 | from .celery import app as celery_app 3 | -------------------------------------------------------------------------------- /Chapter07/myshop/myshop/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for myshop 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', 'myshop.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter07/myshop/myshop/celery.py: -------------------------------------------------------------------------------- 1 | import os 2 | from celery import Celery 3 | 4 | # set the default Django settings module for the 'celery' program. 5 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings') 6 | 7 | app = Celery('myshop') 8 | 9 | app.config_from_object('django.conf:settings', namespace='CELERY') 10 | app.autodiscover_tasks() 11 | -------------------------------------------------------------------------------- /Chapter07/myshop/myshop/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import path, include 3 | from django.conf import settings 4 | from django.conf.urls.static import static 5 | 6 | urlpatterns = [ 7 | path('admin/', admin.site.urls), 8 | path('cart/', include('cart.urls', namespace='cart')), 9 | path('orders/', include('orders.urls', namespace='orders')), 10 | path('', include('shop.urls', namespace='shop')), 11 | ] 12 | 13 | if settings.DEBUG: 14 | urlpatterns += static(settings.MEDIA_URL, 15 | document_root=settings.MEDIA_ROOT) 16 | -------------------------------------------------------------------------------- /Chapter07/myshop/myshop/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for myshop 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', 'myshop.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter07/myshop/orders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter07/myshop/orders/__init__.py -------------------------------------------------------------------------------- /Chapter07/myshop/orders/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Order, OrderItem 3 | 4 | 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | raw_id_fields = ['product'] 8 | 9 | 10 | @admin.register(Order) 11 | class OrderAdmin(admin.ModelAdmin): 12 | list_display = ['id', 'first_name', 'last_name', 'email', 13 | 'address', 'postal_code', 'city', 'paid', 14 | 'created', 'updated'] 15 | list_filter = ['paid', 'created', 'updated'] 16 | inlines = [OrderItemInline] 17 | -------------------------------------------------------------------------------- /Chapter07/myshop/orders/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class OrdersConfig(AppConfig): 5 | name = 'orders' 6 | -------------------------------------------------------------------------------- /Chapter07/myshop/orders/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from .models import Order 3 | 4 | 5 | class OrderCreateForm(forms.ModelForm): 6 | class Meta: 7 | model = Order 8 | fields = ['first_name', 'last_name', 'email', 'address', 9 | 'postal_code', 'city'] 10 | -------------------------------------------------------------------------------- /Chapter07/myshop/orders/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter07/myshop/orders/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter07/myshop/orders/templates/orders/order/created.html: -------------------------------------------------------------------------------- 1 | {% extends "shop/base.html" %} 2 | 3 | {% block title %} 4 | Thank you 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

Thank you

9 |

Your order has been successfully completed. Your order number is 10 | {{ order.id }}.

11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter07/myshop/orders/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter07/myshop/orders/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'orders' 5 | 6 | urlpatterns = [ 7 | path('create/', views.order_create, name='order_create'), 8 | ] 9 | -------------------------------------------------------------------------------- /Chapter07/myshop/shop/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter07/myshop/shop/__init__.py -------------------------------------------------------------------------------- /Chapter07/myshop/shop/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Category, Product 3 | 4 | 5 | @admin.register(Category) 6 | class CategoryAdmin(admin.ModelAdmin): 7 | list_display = ['name', 'slug'] 8 | prepopulated_fields = {'slug': ('name',)} 9 | 10 | @admin.register(Product) 11 | class ProductAdmin(admin.ModelAdmin): 12 | list_display = ['name', 'slug', 'price', 13 | 'available', 'created', 'updated'] 14 | list_filter = ['available', 'created', 'updated'] 15 | list_editable = ['price', 'available'] 16 | prepopulated_fields = {'slug': ('name',)} 17 | -------------------------------------------------------------------------------- /Chapter07/myshop/shop/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ShopConfig(AppConfig): 5 | name = 'shop' 6 | -------------------------------------------------------------------------------- /Chapter07/myshop/shop/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter07/myshop/shop/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter07/myshop/shop/static/img/no_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter07/myshop/shop/static/img/no_image.png -------------------------------------------------------------------------------- /Chapter07/myshop/shop/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter07/myshop/shop/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'shop' 5 | 6 | urlpatterns = [ 7 | path('', views.product_list, name='product_list'), 8 | path('/', views.product_list, name='product_list_by_category'), 9 | path('//', views.product_detail, name='product_detail'), 10 | ] 11 | -------------------------------------------------------------------------------- /Chapter08/myshop/cart/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/cart/__init__.py -------------------------------------------------------------------------------- /Chapter08/myshop/cart/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/cart/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CartConfig(AppConfig): 5 | name = 'cart' 6 | -------------------------------------------------------------------------------- /Chapter08/myshop/cart/context_processors.py: -------------------------------------------------------------------------------- 1 | from .cart import Cart 2 | 3 | 4 | def cart(request): 5 | return {'cart': Cart(request)} 6 | -------------------------------------------------------------------------------- /Chapter08/myshop/cart/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | 4 | PRODUCT_QUANTITY_CHOICES = [(i, str(i)) for i in range(1, 21)] 5 | 6 | 7 | class CartAddProductForm(forms.Form): 8 | quantity = forms.TypedChoiceField( 9 | choices=PRODUCT_QUANTITY_CHOICES, 10 | coerce=int) 11 | override = forms.BooleanField(required=False, 12 | initial=False, 13 | widget=forms.HiddenInput) 14 | -------------------------------------------------------------------------------- /Chapter08/myshop/cart/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/cart/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter08/myshop/cart/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/cart/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/cart/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'cart' 5 | 6 | urlpatterns = [ 7 | path('', views.cart_detail, name='cart_detail'), 8 | path('add//', views.cart_add, name='cart_add'), 9 | path('remove//', views.cart_remove, name='cart_remove'), 10 | ] 11 | -------------------------------------------------------------------------------- /Chapter08/myshop/myshop/__init__.py: -------------------------------------------------------------------------------- 1 | # import celery 2 | from .celery import app as celery_app 3 | -------------------------------------------------------------------------------- /Chapter08/myshop/myshop/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for myshop 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', 'myshop.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter08/myshop/myshop/celery.py: -------------------------------------------------------------------------------- 1 | import os 2 | from celery import Celery 3 | 4 | # set the default Django settings module for the 'celery' program. 5 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings') 6 | 7 | app = Celery('myshop') 8 | 9 | app.config_from_object('django.conf:settings', namespace='CELERY') 10 | app.autodiscover_tasks() 11 | -------------------------------------------------------------------------------- /Chapter08/myshop/myshop/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import path, include 3 | from django.conf import settings 4 | from django.conf.urls.static import static 5 | 6 | urlpatterns = [ 7 | path('admin/', admin.site.urls), 8 | path('cart/', include('cart.urls', namespace='cart')), 9 | path('orders/', include('orders.urls', namespace='orders')), 10 | path('payment/', include('payment.urls', namespace='payment')), 11 | path('', include('shop.urls', namespace='shop')), 12 | ] 13 | 14 | if settings.DEBUG: 15 | urlpatterns += static(settings.MEDIA_URL, 16 | document_root=settings.MEDIA_ROOT) 17 | -------------------------------------------------------------------------------- /Chapter08/myshop/myshop/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for myshop 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', 'myshop.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter08/myshop/orders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/orders/__init__.py -------------------------------------------------------------------------------- /Chapter08/myshop/orders/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class OrdersConfig(AppConfig): 5 | name = 'orders' 6 | -------------------------------------------------------------------------------- /Chapter08/myshop/orders/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from .models import Order 3 | 4 | 5 | class OrderCreateForm(forms.ModelForm): 6 | class Meta: 7 | model = Order 8 | fields = ['first_name', 'last_name', 'email', 'address', 9 | 'postal_code', 'city'] 10 | -------------------------------------------------------------------------------- /Chapter08/myshop/orders/migrations/0002_order_braintree_id.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0 on 2019-12-04 12:21 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('orders', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='order', 15 | name='braintree_id', 16 | field=models.CharField(blank=True, max_length=150), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /Chapter08/myshop/orders/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/orders/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter08/myshop/orders/templates/orders/order/created.html: -------------------------------------------------------------------------------- 1 | {% extends "shop/base.html" %} 2 | 3 | {% block title %} 4 | Thank you 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

Thank you

9 |

Your order has been successfully completed. Your order number is 10 | {{ order.id }}.

11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter08/myshop/orders/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/orders/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'orders' 5 | 6 | urlpatterns = [ 7 | path('create/', views.order_create, name='order_create'), 8 | path('admin/order//', views.admin_order_detail, name='admin_order_detail'), 9 | path('admin/order//pdf/', views.admin_order_pdf, name='admin_order_pdf'), 10 | 11 | ] 12 | -------------------------------------------------------------------------------- /Chapter08/myshop/payment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/payment/__init__.py -------------------------------------------------------------------------------- /Chapter08/myshop/payment/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/payment/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class PaymentConfig(AppConfig): 5 | name = 'payment' 6 | -------------------------------------------------------------------------------- /Chapter08/myshop/payment/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/payment/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter08/myshop/payment/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/payment/templates/payment/canceled.html: -------------------------------------------------------------------------------- 1 | {% extends "shop/base.html" %} 2 | 3 | {% block title %}Payment canceled{% endblock %} 4 | 5 | {% block content %} 6 |

Your payment has not been processed

7 |

There was a problem processing your payment.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter08/myshop/payment/templates/payment/done.html: -------------------------------------------------------------------------------- 1 | {% extends "shop/base.html" %} 2 | 3 | {% block title %}Payment successful{% endblock %} 4 | 5 | {% block content %} 6 |

Your payment was successful

7 |

Your payment has been processed successfully.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter08/myshop/payment/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/payment/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'payment' 5 | 6 | urlpatterns = [ 7 | path('process/', views.payment_process, name='process'), 8 | path('done/', views.payment_done, name='done'), 9 | path('canceled/', views.payment_canceled, name='canceled'), 10 | ] 11 | -------------------------------------------------------------------------------- /Chapter08/myshop/shop/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/shop/__init__.py -------------------------------------------------------------------------------- /Chapter08/myshop/shop/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Category, Product 3 | 4 | 5 | @admin.register(Category) 6 | class CategoryAdmin(admin.ModelAdmin): 7 | list_display = ['name', 'slug'] 8 | prepopulated_fields = {'slug': ('name',)} 9 | 10 | @admin.register(Product) 11 | class ProductAdmin(admin.ModelAdmin): 12 | list_display = ['name', 'slug', 'price', 13 | 'available', 'created', 'updated'] 14 | list_filter = ['available', 'created', 'updated'] 15 | list_editable = ['price', 'available'] 16 | prepopulated_fields = {'slug': ('name',)} 17 | -------------------------------------------------------------------------------- /Chapter08/myshop/shop/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ShopConfig(AppConfig): 5 | name = 'shop' 6 | -------------------------------------------------------------------------------- /Chapter08/myshop/shop/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/shop/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter08/myshop/shop/static/img/no_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/shop/static/img/no_image.png -------------------------------------------------------------------------------- /Chapter08/myshop/shop/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/shop/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'shop' 5 | 6 | urlpatterns = [ 7 | path('', views.product_list, name='product_list'), 8 | path('/', views.product_list, name='product_list_by_category'), 9 | path('//', views.product_detail, name='product_detail'), 10 | ] 11 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/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 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/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 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/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 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/fonts/Roboto-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/static/admin/fonts/Roboto-Bold-webfont.woff -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/fonts/Roboto-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/static/admin/fonts/Roboto-Light-webfont.woff -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/fonts/Roboto-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter08/myshop/static/admin/fonts/Roboto-Regular-webfont.woff -------------------------------------------------------------------------------- /Chapter08/myshop/static/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 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/icon-addlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/icon-alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/icon-changelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/icon-deletelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/icon-no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/icon-viewlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/icon-yes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/inline-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/tooltag-add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/img/tooltag-arrowright.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/js/cancel.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 'use strict'; 3 | $(function() { 4 | $('.cancel-link').on('click', function(e) { 5 | e.preventDefault(); 6 | if (window.location.search.indexOf('&_popup=1') === -1) { 7 | window.history.back(); // Go back if not a popup. 8 | } else { 9 | window.close(); // Otherwise, close the popup. 10 | } 11 | }); 12 | }); 13 | })(django.jQuery); 14 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/js/jquery.init.js: -------------------------------------------------------------------------------- 1 | /*global django:true, jQuery:false*/ 2 | /* Puts the included jQuery into our own namespace using noConflict and passing 3 | * it 'true'. This ensures that the included jQuery doesn't pollute the global 4 | * namespace (i.e. this preserves pre-existing values for both window.$ and 5 | * window.jQuery). 6 | */ 7 | var django = django || {}; 8 | django.jQuery = jQuery.noConflict(true); 9 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/admin/js/popup_response.js: -------------------------------------------------------------------------------- 1 | /*global opener */ 2 | (function() { 3 | 'use strict'; 4 | var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); 5 | switch(initData.action) { 6 | case 'change': 7 | opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value); 8 | break; 9 | case 'delete': 10 | opener.dismissDeleteRelatedObjectPopup(window, initData.value); 11 | break; 12 | default: 13 | opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj); 14 | break; 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /Chapter08/myshop/static/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);0/', views.cart_add, name='cart_add'), 9 | path('remove//', views.cart_remove, name='cart_remove'), 10 | ] 11 | -------------------------------------------------------------------------------- /Chapter09/myshop/coupons/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/coupons/__init__.py -------------------------------------------------------------------------------- /Chapter09/myshop/coupons/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Coupon 3 | 4 | 5 | @admin.register(Coupon) 6 | class CouponAdmin(admin.ModelAdmin): 7 | list_display = ['code', 'valid_from', 'valid_to', 8 | 'discount', 'active'] 9 | list_filter = ['active', 'valid_from', 'valid_to'] 10 | search_fields = ['code'] 11 | -------------------------------------------------------------------------------- /Chapter09/myshop/coupons/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CouponsConfig(AppConfig): 5 | name = 'coupons' 6 | -------------------------------------------------------------------------------- /Chapter09/myshop/coupons/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.utils.translation import gettext_lazy as _ 3 | 4 | 5 | class CouponApplyForm(forms.Form): 6 | code = forms.CharField(label=_('Coupon')) 7 | -------------------------------------------------------------------------------- /Chapter09/myshop/coupons/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/coupons/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter09/myshop/coupons/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.core.validators import MinValueValidator, \ 3 | MaxValueValidator 4 | 5 | 6 | class Coupon(models.Model): 7 | code = models.CharField(max_length=50, 8 | unique=True) 9 | valid_from = models.DateTimeField() 10 | valid_to = models.DateTimeField() 11 | discount = models.IntegerField( 12 | validators=[MinValueValidator(0), 13 | MaxValueValidator(100)]) 14 | active = models.BooleanField() 15 | 16 | def __str__(self): 17 | return self.code 18 | -------------------------------------------------------------------------------- /Chapter09/myshop/coupons/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/coupons/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'coupons' 5 | 6 | urlpatterns = [ 7 | path('apply/', views.coupon_apply, name='apply'), 8 | ] 9 | -------------------------------------------------------------------------------- /Chapter09/myshop/locale/en/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/locale/en/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /Chapter09/myshop/locale/es/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/locale/es/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /Chapter09/myshop/myshop/__init__.py: -------------------------------------------------------------------------------- 1 | # import celery 2 | from .celery import app as celery_app 3 | -------------------------------------------------------------------------------- /Chapter09/myshop/myshop/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for myshop 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', 'myshop.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter09/myshop/myshop/celery.py: -------------------------------------------------------------------------------- 1 | import os 2 | from celery import Celery 3 | 4 | # set the default Django settings module for the 'celery' program. 5 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings') 6 | 7 | app = Celery('myshop') 8 | 9 | app.config_from_object('django.conf:settings', namespace='CELERY') 10 | app.autodiscover_tasks() 11 | -------------------------------------------------------------------------------- /Chapter09/myshop/myshop/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for myshop 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', 'myshop.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter09/myshop/orders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/orders/__init__.py -------------------------------------------------------------------------------- /Chapter09/myshop/orders/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class OrdersConfig(AppConfig): 5 | name = 'orders' 6 | -------------------------------------------------------------------------------- /Chapter09/myshop/orders/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from localflavor.us.forms import USZipCodeField 3 | from .models import Order 4 | 5 | 6 | class OrderCreateForm(forms.ModelForm): 7 | postal_code = USZipCodeField() 8 | 9 | class Meta: 10 | model = Order 11 | fields = ['first_name', 'last_name', 'email', 'address', 12 | 'postal_code', 'city'] 13 | -------------------------------------------------------------------------------- /Chapter09/myshop/orders/locale/en/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/orders/locale/en/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /Chapter09/myshop/orders/locale/es/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/orders/locale/es/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /Chapter09/myshop/orders/migrations/0002_order_braintree_id.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0 on 2019-12-04 12:21 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('orders', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='order', 15 | name='braintree_id', 16 | field=models.CharField(blank=True, max_length=150), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /Chapter09/myshop/orders/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/orders/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter09/myshop/orders/templates/orders/order/created.html: -------------------------------------------------------------------------------- 1 | {% extends "shop/base.html" %} 2 | {% load i18n %} 3 | 4 | {% block title %} 5 | {% trans "Thank you" %} 6 | {% endblock %} 7 | 8 | {% block content %} 9 |

{% trans "Thank you" %}

10 | {% blocktrans with order_id=order.id %} 11 |

Your order has been successfully completed. Your order number is {{ order_id }}.

12 | {% endblocktrans %} 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Chapter09/myshop/orders/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/orders/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from django.utils.translation import gettext_lazy as _ 3 | from . import views 4 | 5 | app_name = 'orders' 6 | 7 | urlpatterns = [ 8 | path(_('create/'), views.order_create, name='order_create'), 9 | path('admin/order//', views.admin_order_detail, name='admin_order_detail'), 10 | path('admin/order//pdf/', views.admin_order_pdf, name='admin_order_pdf'), 11 | 12 | ] 13 | -------------------------------------------------------------------------------- /Chapter09/myshop/payment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/payment/__init__.py -------------------------------------------------------------------------------- /Chapter09/myshop/payment/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/payment/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class PaymentConfig(AppConfig): 5 | name = 'payment' 6 | -------------------------------------------------------------------------------- /Chapter09/myshop/payment/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/payment/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter09/myshop/payment/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/payment/templates/payment/canceled.html: -------------------------------------------------------------------------------- 1 | {% extends "shop/base.html" %} 2 | 3 | {% block title %}Payment canceled{% endblock %} 4 | 5 | {% block content %} 6 |

Your payment has not been processed

7 |

There was a problem processing your payment.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter09/myshop/payment/templates/payment/done.html: -------------------------------------------------------------------------------- 1 | {% extends "shop/base.html" %} 2 | 3 | {% block title %}Payment successful{% endblock %} 4 | 5 | {% block content %} 6 |

Your payment was successful

7 |

Your payment has been processed successfully.

8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Chapter09/myshop/payment/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/payment/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from django.utils.translation import gettext_lazy as _ 3 | from . import views 4 | 5 | app_name = 'payment' 6 | 7 | urlpatterns = [ 8 | path(_('process/'), views.payment_process, name='process'), 9 | path(_('done/'), views.payment_done, name='done'), 10 | path(_('canceled/'), views.payment_canceled, name='canceled'), 11 | ] 12 | -------------------------------------------------------------------------------- /Chapter09/myshop/shop/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/shop/__init__.py -------------------------------------------------------------------------------- /Chapter09/myshop/shop/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ShopConfig(AppConfig): 5 | name = 'shop' 6 | -------------------------------------------------------------------------------- /Chapter09/myshop/shop/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/shop/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter09/myshop/shop/static/img/no_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/shop/static/img/no_image.png -------------------------------------------------------------------------------- /Chapter09/myshop/shop/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/shop/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'shop' 5 | 6 | urlpatterns = [ 7 | path('', views.product_list, name='product_list'), 8 | path('/', views.product_list, name='product_list_by_category'), 9 | path('//', views.product_detail, name='product_detail'), 10 | ] 11 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/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 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/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 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/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 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/fonts/Roboto-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/static/admin/fonts/Roboto-Bold-webfont.woff -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/fonts/Roboto-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/static/admin/fonts/Roboto-Light-webfont.woff -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/fonts/Roboto-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter09/myshop/static/admin/fonts/Roboto-Regular-webfont.woff -------------------------------------------------------------------------------- /Chapter09/myshop/static/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 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/icon-addlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/icon-alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/icon-changelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/icon-deletelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/icon-no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/icon-viewlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/icon-yes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/inline-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/tooltag-add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/img/tooltag-arrowright.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/js/cancel.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 'use strict'; 3 | $(function() { 4 | $('.cancel-link').on('click', function(e) { 5 | e.preventDefault(); 6 | if (window.location.search.indexOf('&_popup=1') === -1) { 7 | window.history.back(); // Go back if not a popup. 8 | } else { 9 | window.close(); // Otherwise, close the popup. 10 | } 11 | }); 12 | }); 13 | })(django.jQuery); 14 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/js/jquery.init.js: -------------------------------------------------------------------------------- 1 | /*global django:true, jQuery:false*/ 2 | /* Puts the included jQuery into our own namespace using noConflict and passing 3 | * it 'true'. This ensures that the included jQuery doesn't pollute the global 4 | * namespace (i.e. this preserves pre-existing values for both window.$ and 5 | * window.jQuery). 6 | */ 7 | var django = django || {}; 8 | django.jQuery = jQuery.noConflict(true); 9 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/admin/js/popup_response.js: -------------------------------------------------------------------------------- 1 | /*global opener */ 2 | (function() { 3 | 'use strict'; 4 | var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); 5 | switch(initData.action) { 6 | case 'change': 7 | opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value); 8 | break; 9 | case 'delete': 10 | opener.dismissDeleteRelatedObjectPopup(window, initData.value); 11 | break; 12 | default: 13 | opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj); 14 | break; 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /Chapter09/myshop/static/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);0Delete course "{{ object.title }}" 7 | 8 |
9 |
10 | {% csrf_token %} 11 |

Are you sure you want to delete "{{ object.title }}"?

12 | 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Chapter10/educa/courses/templates/courses/manage/module/formset.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | Edit "{{ course.title }}" 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

Edit "{{ course.title }}"

9 |
10 |

Course modules

11 |
12 | {{ formset }} 13 | {{ formset.management_form }} 14 | {% csrf_token %} 15 | 16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Chapter10/educa/courses/templates/registration/logged_out.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Logged out{% endblock %} 4 | 5 | {% block content %} 6 |

Logged out

7 |
8 |

You have been successfully logged out. 9 | You can log-in again.

10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter10/educa/courses/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter10/educa/courses/templatetags/__init__.py -------------------------------------------------------------------------------- /Chapter10/educa/courses/templatetags/course.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | register = template.Library() 4 | 5 | @register.filter 6 | def model_name(obj): 7 | try: 8 | return obj._meta.model_name 9 | except AttributeError: 10 | return None 11 | -------------------------------------------------------------------------------- /Chapter10/educa/courses/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter10/educa/educa/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter10/educa/educa/__init__.py -------------------------------------------------------------------------------- /Chapter10/educa/educa/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for educa 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', 'educa.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter10/educa/educa/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import path, include 3 | from django.contrib.auth import views as auth_views 4 | 5 | urlpatterns = [ 6 | path('accounts/login/', auth_views.LoginView.as_view(), name='login'), 7 | path('accounts/logout/', auth_views.LogoutView.as_view(), name='logout'), 8 | path('admin/', admin.site.urls), 9 | path('course/', include('courses.urls')), 10 | ] 11 | -------------------------------------------------------------------------------- /Chapter10/educa/educa/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for educa 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', 'educa.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter11/educa/courses/__init__.py -------------------------------------------------------------------------------- /Chapter11/educa/courses/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CoursesConfig(AppConfig): 5 | name = 'courses' 6 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/fixtures/subjects.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "model": "courses.subject", 4 | "pk": 1, 5 | "fields": { 6 | "title": "Mathematics", 7 | "slug": "mathematics" 8 | } 9 | }, 10 | { 11 | "model": "courses.subject", 12 | "pk": 2, 13 | "fields": { 14 | "title": "Music", 15 | "slug": "music" 16 | } 17 | }, 18 | { 19 | "model": "courses.subject", 20 | "pk": 3, 21 | "fields": { 22 | "title": "Physics", 23 | "slug": "physics" 24 | } 25 | }, 26 | { 27 | "model": "courses.subject", 28 | "pk": 4, 29 | "fields": { 30 | "title": "Programming", 31 | "slug": "programming" 32 | } 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.forms.models import inlineformset_factory 3 | from .models import Course, Module 4 | 5 | 6 | ModuleFormSet = inlineformset_factory(Course, 7 | Module, 8 | fields=['title', 9 | 'description'], 10 | extra=2, 11 | can_delete=True) 12 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/migrations/0004_course_students.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0 on 2019-12-23 08:52 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 11 | ('courses', '0003_auto_20191214_1253'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='course', 17 | name='students', 18 | field=models.ManyToManyField(blank=True, related_name='courses_joined', to=settings.AUTH_USER_MODEL), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter11/educa/courses/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter11/educa/courses/templates/courses/content/file.html: -------------------------------------------------------------------------------- 1 |

Download file

2 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/templates/courses/content/image.html: -------------------------------------------------------------------------------- 1 |

{{ item.title }}

2 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/templates/courses/content/text.html: -------------------------------------------------------------------------------- 1 | {{ item.content|linebreaks }} 2 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/templates/courses/content/video.html: -------------------------------------------------------------------------------- 1 | {% load embed_video_tags %} 2 | {% video item.url "small" %} 3 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/templates/courses/manage/course/delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Delete course{% endblock %} 4 | 5 | {% block content %} 6 |

Delete course "{{ object.title }}"

7 | 8 |
9 |
10 | {% csrf_token %} 11 |

Are you sure you want to delete "{{ object.title }}"?

12 | 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/templates/courses/manage/module/formset.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | Edit "{{ course.title }}" 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

Edit "{{ course.title }}"

9 |
10 |

Course modules

11 |
12 | {{ formset }} 13 | {{ formset.management_form }} 14 | {% csrf_token %} 15 | 16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/templates/registration/logged_out.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Logged out{% endblock %} 4 | 5 | {% block content %} 6 |

Logged out

7 |
8 |

You have been successfully logged out. 9 | You can log-in again.

10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter11/educa/courses/templatetags/__init__.py -------------------------------------------------------------------------------- /Chapter11/educa/courses/templatetags/course.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | register = template.Library() 4 | 5 | @register.filter 6 | def model_name(obj): 7 | try: 8 | return obj._meta.model_name 9 | except AttributeError: 10 | return None 11 | -------------------------------------------------------------------------------- /Chapter11/educa/courses/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter11/educa/educa/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter11/educa/educa/__init__.py -------------------------------------------------------------------------------- /Chapter11/educa/educa/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for educa 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', 'educa.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter11/educa/educa/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for educa 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', 'educa.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter11/educa/students/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter11/educa/students/__init__.py -------------------------------------------------------------------------------- /Chapter11/educa/students/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Chapter11/educa/students/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class StudentsConfig(AppConfig): 5 | name = 'students' 6 | -------------------------------------------------------------------------------- /Chapter11/educa/students/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from courses.models import Course 3 | 4 | 5 | class CourseEnrollForm(forms.Form): 6 | course = forms.ModelChoiceField(queryset=Course.objects.all(), 7 | widget=forms.HiddenInput) 8 | -------------------------------------------------------------------------------- /Chapter11/educa/students/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter11/educa/students/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter11/educa/students/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Chapter11/educa/students/templates/students/student/registration.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | Sign up 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

9 | Sign up 10 |

11 |
12 |

Enter your details to create an account:

13 |
14 | {{ form.as_p }} 15 | {% csrf_token %} 16 |

17 |
18 |
19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /Chapter11/educa/students/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter12/educa/courses/__init__.py -------------------------------------------------------------------------------- /Chapter12/educa/courses/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter12/educa/courses/api/__init__.py -------------------------------------------------------------------------------- /Chapter12/educa/courses/api/permissions.py: -------------------------------------------------------------------------------- 1 | from rest_framework.permissions import BasePermission 2 | 3 | 4 | class IsEnrolled(BasePermission): 5 | def has_object_permission(self, request, view, obj): 6 | return obj.students.filter(id=request.user.id).exists() 7 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, include 2 | from rest_framework import routers 3 | from . import views 4 | 5 | app_name = 'courses' 6 | 7 | router = routers.DefaultRouter() 8 | router.register('courses', views.CourseViewSet) 9 | 10 | urlpatterns = [ 11 | path('subjects/', 12 | views.SubjectListView.as_view(), 13 | name='subject_list'), 14 | path('subjects//', 15 | views.SubjectDetailView.as_view(), 16 | name='subject_detail'), 17 | # path('courses//enroll/', 18 | # views.CourseEnrollView.as_view(), 19 | # name='course_enroll'), 20 | path('', include(router.urls)), 21 | ] 22 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CoursesConfig(AppConfig): 5 | name = 'courses' 6 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/fixtures/subjects.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "model": "courses.subject", 4 | "pk": 1, 5 | "fields": { 6 | "title": "Mathematics", 7 | "slug": "mathematics" 8 | } 9 | }, 10 | { 11 | "model": "courses.subject", 12 | "pk": 2, 13 | "fields": { 14 | "title": "Music", 15 | "slug": "music" 16 | } 17 | }, 18 | { 19 | "model": "courses.subject", 20 | "pk": 3, 21 | "fields": { 22 | "title": "Physics", 23 | "slug": "physics" 24 | } 25 | }, 26 | { 27 | "model": "courses.subject", 28 | "pk": 4, 29 | "fields": { 30 | "title": "Programming", 31 | "slug": "programming" 32 | } 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.forms.models import inlineformset_factory 3 | from .models import Course, Module 4 | 5 | 6 | ModuleFormSet = inlineformset_factory(Course, 7 | Module, 8 | fields=['title', 9 | 'description'], 10 | extra=2, 11 | can_delete=True) 12 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/migrations/0004_course_students.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0 on 2019-12-23 08:52 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 11 | ('courses', '0003_auto_20191214_1253'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='course', 17 | name='students', 18 | field=models.ManyToManyField(blank=True, related_name='courses_joined', to=settings.AUTH_USER_MODEL), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter12/educa/courses/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter12/educa/courses/templates/courses/content/file.html: -------------------------------------------------------------------------------- 1 |

Download file

2 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/templates/courses/content/image.html: -------------------------------------------------------------------------------- 1 |

{{ item.title }}

2 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/templates/courses/content/text.html: -------------------------------------------------------------------------------- 1 | {{ item.content|linebreaks }} 2 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/templates/courses/content/video.html: -------------------------------------------------------------------------------- 1 | {% load embed_video_tags %} 2 | {% video item.url "small" %} 3 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/templates/courses/manage/course/delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Delete course{% endblock %} 4 | 5 | {% block content %} 6 |

Delete course "{{ object.title }}"

7 | 8 |
9 |
10 | {% csrf_token %} 11 |

Are you sure you want to delete "{{ object.title }}"?

12 | 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/templates/courses/manage/module/formset.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | Edit "{{ course.title }}" 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

Edit "{{ course.title }}"

9 |
10 |

Course modules

11 |
12 | {{ formset }} 13 | {{ formset.management_form }} 14 | {% csrf_token %} 15 | 16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/templates/registration/logged_out.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Logged out{% endblock %} 4 | 5 | {% block content %} 6 |

Logged out

7 |
8 |

You have been successfully logged out. 9 | You can log-in again.

10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter12/educa/courses/templatetags/__init__.py -------------------------------------------------------------------------------- /Chapter12/educa/courses/templatetags/course.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | register = template.Library() 4 | 5 | @register.filter 6 | def model_name(obj): 7 | try: 8 | return obj._meta.model_name 9 | except AttributeError: 10 | return None 11 | -------------------------------------------------------------------------------- /Chapter12/educa/courses/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter12/educa/educa/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter12/educa/educa/__init__.py -------------------------------------------------------------------------------- /Chapter12/educa/educa/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for educa 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', 'educa.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter12/educa/educa/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for educa 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', 'educa.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter12/educa/students/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter12/educa/students/__init__.py -------------------------------------------------------------------------------- /Chapter12/educa/students/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Chapter12/educa/students/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class StudentsConfig(AppConfig): 5 | name = 'students' 6 | -------------------------------------------------------------------------------- /Chapter12/educa/students/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from courses.models import Course 3 | 4 | 5 | class CourseEnrollForm(forms.Form): 6 | course = forms.ModelChoiceField(queryset=Course.objects.all(), 7 | widget=forms.HiddenInput) 8 | -------------------------------------------------------------------------------- /Chapter12/educa/students/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter12/educa/students/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter12/educa/students/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Chapter12/educa/students/templates/students/student/registration.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | Sign up 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

9 | Sign up 10 |

11 |
12 |

Enter your details to create an account:

13 |
14 | {{ form.as_p }} 15 | {% csrf_token %} 16 |

17 |
18 |
19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /Chapter12/educa/students/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter13/educa/chat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter13/educa/chat/__init__.py -------------------------------------------------------------------------------- /Chapter13/educa/chat/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Chapter13/educa/chat/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ChatConfig(AppConfig): 5 | name = 'chat' 6 | -------------------------------------------------------------------------------- /Chapter13/educa/chat/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter13/educa/chat/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter13/educa/chat/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Chapter13/educa/chat/routing.py: -------------------------------------------------------------------------------- 1 | from django.urls import re_path 2 | from . import consumers 3 | 4 | websocket_urlpatterns = [ 5 | re_path(r'ws/chat/room/(?P\d+)/$', consumers.ChatConsumer), 6 | ] 7 | -------------------------------------------------------------------------------- /Chapter13/educa/chat/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter13/educa/chat/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'chat' 5 | 6 | urlpatterns = [ 7 | path('room//', views.course_chat_room, 8 | name='course_chat_room'), 9 | ] 10 | -------------------------------------------------------------------------------- /Chapter13/educa/chat/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, get_object_or_404 2 | from django.http import HttpResponseForbidden 3 | from django.contrib.auth.decorators import login_required 4 | 5 | 6 | @login_required 7 | def course_chat_room(request, course_id): 8 | try: 9 | # retrieve course with given id joined by the current user 10 | course = request.user.courses_joined.get(id=course_id) 11 | except: 12 | # user is not a student of the course or course does not exist 13 | return HttpResponseForbidden() 14 | return render(request, 'chat/room.html', {'course': course}) 15 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter13/educa/courses/__init__.py -------------------------------------------------------------------------------- /Chapter13/educa/courses/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter13/educa/courses/api/__init__.py -------------------------------------------------------------------------------- /Chapter13/educa/courses/api/permissions.py: -------------------------------------------------------------------------------- 1 | from rest_framework.permissions import BasePermission 2 | 3 | 4 | class IsEnrolled(BasePermission): 5 | def has_object_permission(self, request, view, obj): 6 | return obj.students.filter(id=request.user.id).exists() 7 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, include 2 | from rest_framework import routers 3 | from . import views 4 | 5 | app_name = 'courses' 6 | 7 | router = routers.DefaultRouter() 8 | router.register('courses', views.CourseViewSet) 9 | 10 | urlpatterns = [ 11 | path('subjects/', 12 | views.SubjectListView.as_view(), 13 | name='subject_list'), 14 | path('subjects//', 15 | views.SubjectDetailView.as_view(), 16 | name='subject_detail'), 17 | # path('courses//enroll/', 18 | # views.CourseEnrollView.as_view(), 19 | # name='course_enroll'), 20 | path('', include(router.urls)), 21 | ] 22 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CoursesConfig(AppConfig): 5 | name = 'courses' 6 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/fixtures/subjects.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "model": "courses.subject", 4 | "pk": 1, 5 | "fields": { 6 | "title": "Mathematics", 7 | "slug": "mathematics" 8 | } 9 | }, 10 | { 11 | "model": "courses.subject", 12 | "pk": 2, 13 | "fields": { 14 | "title": "Music", 15 | "slug": "music" 16 | } 17 | }, 18 | { 19 | "model": "courses.subject", 20 | "pk": 3, 21 | "fields": { 22 | "title": "Physics", 23 | "slug": "physics" 24 | } 25 | }, 26 | { 27 | "model": "courses.subject", 28 | "pk": 4, 29 | "fields": { 30 | "title": "Programming", 31 | "slug": "programming" 32 | } 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.forms.models import inlineformset_factory 3 | from .models import Course, Module 4 | 5 | 6 | ModuleFormSet = inlineformset_factory(Course, 7 | Module, 8 | fields=['title', 9 | 'description'], 10 | extra=2, 11 | can_delete=True) 12 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter13/educa/courses/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter13/educa/courses/templates/courses/content/file.html: -------------------------------------------------------------------------------- 1 |

Download file

2 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/templates/courses/content/image.html: -------------------------------------------------------------------------------- 1 |

{{ item.title }}

2 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/templates/courses/content/text.html: -------------------------------------------------------------------------------- 1 | {{ item.content|linebreaks }} 2 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/templates/courses/content/video.html: -------------------------------------------------------------------------------- 1 | {% load embed_video_tags %} 2 | {% video item.url "small" %} 3 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/templates/courses/manage/course/delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Delete course{% endblock %} 4 | 5 | {% block content %} 6 |

Delete course "{{ object.title }}"

7 | 8 |
9 |
10 | {% csrf_token %} 11 |

Are you sure you want to delete "{{ object.title }}"?

12 | 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/templates/courses/manage/module/formset.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | Edit "{{ course.title }}" 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

Edit "{{ course.title }}"

9 |
10 |

Course modules

11 |
12 | {{ formset }} 13 | {{ formset.management_form }} 14 | {% csrf_token %} 15 | 16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/templates/registration/logged_out.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Logged out{% endblock %} 4 | 5 | {% block content %} 6 |

Logged out

7 |
8 |

You have been successfully logged out. 9 | You can log-in again.

10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter13/educa/courses/templatetags/__init__.py -------------------------------------------------------------------------------- /Chapter13/educa/courses/templatetags/course.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | register = template.Library() 4 | 5 | @register.filter 6 | def model_name(obj): 7 | try: 8 | return obj._meta.model_name 9 | except AttributeError: 10 | return None 11 | -------------------------------------------------------------------------------- /Chapter13/educa/courses/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter13/educa/educa/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter13/educa/educa/__init__.py -------------------------------------------------------------------------------- /Chapter13/educa/educa/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for educa 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', 'educa.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Chapter13/educa/educa/routing.py: -------------------------------------------------------------------------------- 1 | from channels.auth import AuthMiddlewareStack 2 | from channels.routing import ProtocolTypeRouter, URLRouter 3 | import chat.routing 4 | 5 | application = ProtocolTypeRouter({ 6 | 'websocket': AuthMiddlewareStack( 7 | URLRouter( 8 | chat.routing.websocket_urlpatterns 9 | ) 10 | ), 11 | }) 12 | -------------------------------------------------------------------------------- /Chapter13/educa/educa/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for educa 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', 'educa.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter13/educa/students/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter13/educa/students/__init__.py -------------------------------------------------------------------------------- /Chapter13/educa/students/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Chapter13/educa/students/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class StudentsConfig(AppConfig): 5 | name = 'students' 6 | -------------------------------------------------------------------------------- /Chapter13/educa/students/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from courses.models import Course 3 | 4 | 5 | class CourseEnrollForm(forms.Form): 6 | course = forms.ModelChoiceField(queryset=Course.objects.all(), 7 | widget=forms.HiddenInput) 8 | -------------------------------------------------------------------------------- /Chapter13/educa/students/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter13/educa/students/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter13/educa/students/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Chapter13/educa/students/templates/students/student/registration.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | Sign up 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

9 | Sign up 10 |

11 |
12 |

Enter your details to create an account:

13 |
14 | {{ form.as_p }} 15 | {% csrf_token %} 16 |

17 |
18 |
19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /Chapter13/educa/students/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter14/educa/chat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/chat/__init__.py -------------------------------------------------------------------------------- /Chapter14/educa/chat/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Chapter14/educa/chat/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ChatConfig(AppConfig): 5 | name = 'chat' 6 | -------------------------------------------------------------------------------- /Chapter14/educa/chat/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/chat/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter14/educa/chat/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Chapter14/educa/chat/routing.py: -------------------------------------------------------------------------------- 1 | from django.urls import re_path 2 | from . import consumers 3 | 4 | websocket_urlpatterns = [ 5 | re_path(r'ws/chat/room/(?P\d+)/$', consumers.ChatConsumer), 6 | ] 7 | -------------------------------------------------------------------------------- /Chapter14/educa/chat/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter14/educa/chat/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'chat' 5 | 6 | urlpatterns = [ 7 | path('room//', views.course_chat_room, 8 | name='course_chat_room'), 9 | ] 10 | -------------------------------------------------------------------------------- /Chapter14/educa/chat/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, get_object_or_404 2 | from django.http import HttpResponseForbidden 3 | from django.contrib.auth.decorators import login_required 4 | 5 | 6 | @login_required 7 | def course_chat_room(request, course_id): 8 | try: 9 | # retrieve course with given id joined by the current user 10 | course = request.user.courses_joined.get(id=course_id) 11 | except: 12 | # user is not a student of the course or course does not exist 13 | return HttpResponseForbidden() 14 | return render(request, 'chat/room.html', {'course': course}) 15 | -------------------------------------------------------------------------------- /Chapter14/educa/config/uwsgi.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | # variables 3 | projectname = educa 4 | base = /home/projects/educa 5 | 6 | # configuration 7 | master = true 8 | virtualenv = /home/env/%(projectname) 9 | pythonpath = %(base) 10 | chdir = %(base) 11 | env = DJANGO_SETTINGS_MODULE=%(projectname).settings.pro 12 | module = %(projectname).wsgi:application 13 | socket = /tmp/%(projectname).sock 14 | chmod-socket = 666 15 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/courses/__init__.py -------------------------------------------------------------------------------- /Chapter14/educa/courses/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/courses/api/__init__.py -------------------------------------------------------------------------------- /Chapter14/educa/courses/api/permissions.py: -------------------------------------------------------------------------------- 1 | from rest_framework.permissions import BasePermission 2 | 3 | 4 | class IsEnrolled(BasePermission): 5 | def has_object_permission(self, request, view, obj): 6 | return obj.students.filter(id=request.user.id).exists() 7 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CoursesConfig(AppConfig): 5 | name = 'courses' 6 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/fixtures/subjects.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "model": "courses.subject", 4 | "pk": 1, 5 | "fields": { 6 | "title": "Mathematics", 7 | "slug": "mathematics" 8 | } 9 | }, 10 | { 11 | "model": "courses.subject", 12 | "pk": 2, 13 | "fields": { 14 | "title": "Music", 15 | "slug": "music" 16 | } 17 | }, 18 | { 19 | "model": "courses.subject", 20 | "pk": 3, 21 | "fields": { 22 | "title": "Physics", 23 | "slug": "physics" 24 | } 25 | }, 26 | { 27 | "model": "courses.subject", 28 | "pk": 4, 29 | "fields": { 30 | "title": "Programming", 31 | "slug": "programming" 32 | } 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.forms.models import inlineformset_factory 3 | from .models import Course, Module 4 | 5 | 6 | ModuleFormSet = inlineformset_factory(Course, 7 | Module, 8 | fields=['title', 9 | 'description'], 10 | extra=2, 11 | can_delete=True) 12 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/courses/migrations/__init__.py -------------------------------------------------------------------------------- /Chapter14/educa/courses/templates/courses/content/file.html: -------------------------------------------------------------------------------- 1 |

Download file

2 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/templates/courses/content/image.html: -------------------------------------------------------------------------------- 1 |

{{ item.title }}

2 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/templates/courses/content/text.html: -------------------------------------------------------------------------------- 1 | {{ item.content|linebreaks }} 2 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/templates/courses/content/video.html: -------------------------------------------------------------------------------- 1 | {% load embed_video_tags %} 2 | {% video item.url "small" %} 3 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/templates/courses/manage/course/delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Delete course{% endblock %} 4 | 5 | {% block content %} 6 |

Delete course "{{ object.title }}"

7 | 8 |
9 |
10 | {% csrf_token %} 11 |

Are you sure you want to delete "{{ object.title }}"?

12 | 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/templates/courses/manage/module/formset.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | Edit "{{ course.title }}" 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

Edit "{{ course.title }}"

9 |
10 |

Course modules

11 |
12 | {{ formset }} 13 | {{ formset.management_form }} 14 | {% csrf_token %} 15 | 16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/templates/registration/logged_out.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Logged out{% endblock %} 4 | 5 | {% block content %} 6 |

Logged out

7 |
8 |

You have been successfully logged out. 9 | You can log-in again.

10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/courses/templatetags/__init__.py -------------------------------------------------------------------------------- /Chapter14/educa/courses/templatetags/course.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | register = template.Library() 4 | 5 | @register.filter 6 | def model_name(obj): 7 | try: 8 | return obj._meta.model_name 9 | except AttributeError: 10 | return None 11 | -------------------------------------------------------------------------------- /Chapter14/educa/courses/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Chapter14/educa/educa/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/educa/__init__.py -------------------------------------------------------------------------------- /Chapter14/educa/educa/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI entrypoint. Configures Django and then runs the application 3 | defined in the ASGI_APPLICATION setting. 4 | """ 5 | 6 | import os 7 | import django 8 | from channels.routing import get_default_application 9 | 10 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings') 11 | django.setup() 12 | application = get_default_application() 13 | -------------------------------------------------------------------------------- /Chapter14/educa/educa/routing.py: -------------------------------------------------------------------------------- 1 | from channels.auth import AuthMiddlewareStack 2 | from channels.routing import ProtocolTypeRouter, URLRouter 3 | import chat.routing 4 | 5 | application = ProtocolTypeRouter({ 6 | 'websocket': AuthMiddlewareStack( 7 | URLRouter( 8 | chat.routing.websocket_urlpatterns 9 | ) 10 | ), 11 | }) 12 | -------------------------------------------------------------------------------- /Chapter14/educa/educa/settings/local.py: -------------------------------------------------------------------------------- 1 | from .base import * 2 | 3 | DEBUG = True 4 | 5 | DATABASES = { 6 | 'default': { 7 | 'ENGINE': 'django.db.backends.sqlite3', 8 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter14/educa/educa/settings/pro.py: -------------------------------------------------------------------------------- 1 | from .base import * 2 | 3 | DEBUG = False 4 | 5 | ADMINS = ( 6 | ('Antonio M', 'email@mydomain.com'), 7 | ) 8 | 9 | ALLOWED_HOSTS = ['.educaproject.com'] 10 | 11 | DATABASES = { 12 | 'default': { 13 | 'ENGINE': 'django.db.backends.postgresql', 14 | 'NAME': 'educa', 15 | 'USER': 'educa', 16 | 'PASSWORD': '*****', 17 | } 18 | } 19 | 20 | # SSL config 21 | SECURE_SSL_REDIRECT = True 22 | CSRF_COOKIE_SECURE = True 23 | -------------------------------------------------------------------------------- /Chapter14/educa/educa/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for educa 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', 'educa.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Chapter14/educa/logs/nginx_error.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/logs/nginx_error.log -------------------------------------------------------------------------------- /Chapter14/educa/static/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 | -------------------------------------------------------------------------------- /Chapter14/educa/static/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 | -------------------------------------------------------------------------------- /Chapter14/educa/static/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 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/fonts/Roboto-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/static/admin/fonts/Roboto-Bold-webfont.woff -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/fonts/Roboto-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/static/admin/fonts/Roboto-Light-webfont.woff -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/fonts/Roboto-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Django-3-by-Example/68b33d550d423cf4e9dcfe262e84f2a7e48ee911/Chapter14/educa/static/admin/fonts/Roboto-Regular-webfont.woff -------------------------------------------------------------------------------- /Chapter14/educa/static/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 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/icon-addlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/icon-alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/icon-changelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/icon-deletelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/icon-no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/icon-viewlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/icon-yes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/inline-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/tooltag-add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/img/tooltag-arrowright.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/js/cancel.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 'use strict'; 3 | $(function() { 4 | $('.cancel-link').on('click', function(e) { 5 | e.preventDefault(); 6 | if (window.location.search.indexOf('&_popup=1') === -1) { 7 | window.history.back(); // Go back if not a popup. 8 | } else { 9 | window.close(); // Otherwise, close the popup. 10 | } 11 | }); 12 | }); 13 | })(django.jQuery); 14 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/js/jquery.init.js: -------------------------------------------------------------------------------- 1 | /*global django:true, jQuery:false*/ 2 | /* Puts the included jQuery into our own namespace using noConflict and passing 3 | * it 'true'. This ensures that the included jQuery doesn't pollute the global 4 | * namespace (i.e. this preserves pre-existing values for both window.$ and 5 | * window.jQuery). 6 | */ 7 | var django = django || {}; 8 | django.jQuery = jQuery.noConflict(true); 9 | -------------------------------------------------------------------------------- /Chapter14/educa/static/admin/js/popup_response.js: -------------------------------------------------------------------------------- 1 | /*global opener */ 2 | (function() { 3 | 'use strict'; 4 | var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); 5 | switch(initData.action) { 6 | case 'change': 7 | opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value); 8 | break; 9 | case 'delete': 10 | opener.dismissDeleteRelatedObjectPopup(window, initData.value); 11 | break; 12 | default: 13 | opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj); 14 | break; 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /Chapter14/educa/static/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);0 9 | Sign up 10 | 11 |
12 |

Enter your details to create an account:

13 |
14 | {{ form.as_p }} 15 | {% csrf_token %} 16 |

17 |
18 |
19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /Chapter14/educa/students/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | --------------------------------------------------------------------------------