├── .gitignore
├── Chapter01
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── mysite
│ ├── blog
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── static
│ │ │ └── css
│ │ │ │ └── blog.css
│ │ ├── templates
│ │ │ └── blog
│ │ │ │ ├── base.html
│ │ │ │ └── post
│ │ │ │ ├── detail.html
│ │ │ │ └── list.html
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── manage.py
│ └── mysite
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
└── requirements.txt
├── Chapter02
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── mysite
│ ├── blog
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── forms.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_alter_post_slug.py
│ │ │ ├── 0003_comment_comment_blog_commen_created_0e6ed4_idx.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── static
│ │ │ └── css
│ │ │ │ └── blog.css
│ │ ├── templates
│ │ │ ├── blog
│ │ │ │ ├── base.html
│ │ │ │ └── post
│ │ │ │ │ ├── comment.html
│ │ │ │ │ ├── detail.html
│ │ │ │ │ ├── includes
│ │ │ │ │ └── comment_form.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
└── requirements.txt
├── Chapter03
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── mysite
│ ├── blog
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── feeds.py
│ │ ├── forms.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_alter_post_slug.py
│ │ │ ├── 0003_comment_comment_blog_commen_created_0e6ed4_idx.py
│ │ │ ├── 0004_post_tags.py
│ │ │ ├── 0005_trigram_ext.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── sitemaps.py
│ │ ├── static
│ │ │ └── css
│ │ │ │ └── blog.css
│ │ ├── templates
│ │ │ ├── blog
│ │ │ │ ├── base.html
│ │ │ │ └── post
│ │ │ │ │ ├── comment.html
│ │ │ │ │ ├── detail.html
│ │ │ │ │ ├── includes
│ │ │ │ │ └── comment_form.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
├── prompts
│ └── task.md
└── requirements.txt
├── Chapter04
├── Dockerfile
├── bookmarks
│ ├── account
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.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
├── do.sh
├── docker-compose.yml
└── requirements.txt
├── Chapter05
├── Dockerfile
├── 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
├── do.sh
├── docker-compose.yml
└── requirements.txt
├── Chapter06
├── Dockerfile
├── 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
│ ├── 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_images.html
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ └── manage.py
├── do.sh
├── docker-compose.yml
└── requirements.txt
├── Chapter07
├── Dockerfile
├── 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
│ ├── images
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── forms.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_image_total_likes_and_more.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_images.html
│ │ │ │ └── ranking.html
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ └── manage.py
├── do.sh
├── docker-compose.yml
├── prompts
│ └── task.md
└── requirements.txt
├── Chapter08
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── 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
└── requirements.txt
├── Chapter09
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── 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_stripe_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
│ │ │ │ ├── completed.html
│ │ │ │ └── process.html
│ │ ├── tests.py
│ │ ├── urls.py
│ │ ├── views.py
│ │ └── webhooks.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
│ │ │ ├── dark_mode.css
│ │ │ ├── dashboard.css
│ │ │ ├── fonts.css
│ │ │ ├── forms.css
│ │ │ ├── login.css
│ │ │ ├── nav_sidebar.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-hidelink.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
│ │ │ ├── admin
│ │ │ ├── DateTimeShortcuts.js
│ │ │ └── RelatedObjectLookups.js
│ │ │ ├── autocomplete.js
│ │ │ ├── calendar.js
│ │ │ ├── cancel.js
│ │ │ ├── change_form.js
│ │ │ ├── collapse.js
│ │ │ ├── core.js
│ │ │ ├── filters.js
│ │ │ ├── inlines.js
│ │ │ ├── jquery.init.js
│ │ │ ├── nav_sidebar.js
│ │ │ ├── popup_response.js
│ │ │ ├── prepopulate.js
│ │ │ ├── prepopulate_init.js
│ │ │ ├── theme.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
└── requirements.txt
├── Chapter10
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── 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
│ ├── 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_stripe_id.py
│ │ │ ├── 0003_order_coupon_order_discount.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
│ │ │ │ ├── completed.html
│ │ │ │ └── process.html
│ │ ├── tests.py
│ │ ├── urls.py
│ │ ├── views.py
│ │ └── webhooks.py
│ ├── shop
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.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
│ │ │ ├── dark_mode.css
│ │ │ ├── dashboard.css
│ │ │ ├── fonts.css
│ │ │ ├── forms.css
│ │ │ ├── login.css
│ │ │ ├── nav_sidebar.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-hidelink.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
│ │ │ ├── admin
│ │ │ ├── DateTimeShortcuts.js
│ │ │ └── RelatedObjectLookups.js
│ │ │ ├── autocomplete.js
│ │ │ ├── calendar.js
│ │ │ ├── cancel.js
│ │ │ ├── change_form.js
│ │ │ ├── collapse.js
│ │ │ ├── core.js
│ │ │ ├── filters.js
│ │ │ ├── inlines.js
│ │ │ ├── jquery.init.js
│ │ │ ├── nav_sidebar.js
│ │ │ ├── popup_response.js
│ │ │ ├── prepopulate.js
│ │ │ ├── prepopulate_init.js
│ │ │ ├── theme.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
└── requirements.txt
├── Chapter11
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── 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.po
│ │ └── es
│ │ │ └── LC_MESSAGES
│ │ │ └── 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.po
│ │ │ └── es
│ │ │ │ └── LC_MESSAGES
│ │ │ │ └── django.po
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_order_stripe_id.py
│ │ │ ├── 0003_order_coupon_order_discount.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
│ │ │ │ ├── completed.html
│ │ │ │ └── process.html
│ │ ├── tests.py
│ │ ├── urls.py
│ │ ├── views.py
│ │ └── webhooks.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
│ │ │ ├── dark_mode.css
│ │ │ ├── dashboard.css
│ │ │ ├── fonts.css
│ │ │ ├── forms.css
│ │ │ ├── login.css
│ │ │ ├── nav_sidebar.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-hidelink.svg
│ │ │ ├── icon-no.svg
│ │ │ ├── icon-unknown-alt.svg
│ │ │ ├── icon-unknown.svg
│ │ │ ├── icon-viewlink.svg
│ │ │ ├── icon-yes.svg
│ │ │ ├── icon_searchbox_rosetta.png
│ │ │ ├── inline-delete.svg
│ │ │ ├── search.svg
│ │ │ ├── selector-icons.svg
│ │ │ ├── sorting-icons.svg
│ │ │ ├── tooltag-add.svg
│ │ │ └── tooltag-arrowright.svg
│ │ └── js
│ │ │ ├── SelectBox.js
│ │ │ ├── SelectFilter2.js
│ │ │ ├── actions.js
│ │ │ ├── admin
│ │ │ ├── DateTimeShortcuts.js
│ │ │ └── RelatedObjectLookups.js
│ │ │ ├── autocomplete.js
│ │ │ ├── calendar.js
│ │ │ ├── cancel.js
│ │ │ ├── change_form.js
│ │ │ ├── collapse.js
│ │ │ ├── core.js
│ │ │ ├── filters.js
│ │ │ ├── inlines.js
│ │ │ ├── jquery.init.js
│ │ │ ├── nav_sidebar.js
│ │ │ ├── popup_response.js
│ │ │ ├── prepopulate.js
│ │ │ ├── prepopulate_init.js
│ │ │ ├── theme.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
│ │ └── parler
│ │ └── admin
│ │ └── parler_admin.css
├── prompts
│ └── task.md
└── requirements.txt
├── Chapter12
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── educa
│ ├── courses
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── fields.py
│ │ ├── fixtures
│ │ │ └── subjects.json
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_video_text_image_file_content.py
│ │ │ ├── 0003_alter_content_options_alter_module_options_and_more.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── static
│ │ │ └── css
│ │ │ │ └── base.css
│ │ ├── templates
│ │ │ ├── base.html
│ │ │ └── registration
│ │ │ │ ├── logged_out.html
│ │ │ │ └── login.html
│ │ ├── tests.py
│ │ └── views.py
│ ├── educa
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ └── manage.py
└── requirements.txt
├── Chapter13
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── educa
│ ├── courses
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── fields.py
│ │ ├── fixtures
│ │ │ └── subjects.json
│ │ ├── forms.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_video_text_image_file_content.py
│ │ │ ├── 0003_alter_content_options_alter_module_options_and_more.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
└── requirements.txt
├── Chapter14
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── educa
│ ├── courses
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── fields.py
│ │ ├── fixtures
│ │ │ └── subjects.json
│ │ ├── forms.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_video_text_image_file_content.py
│ │ │ ├── 0003_alter_content_options_alter_module_options_and_more.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
└── requirements.txt
├── Chapter15
├── Dockerfile
├── api_examples
│ └── enroll_all.py
├── do.sh
├── docker-compose.yml
├── educa
│ ├── courses
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── api
│ │ │ ├── __init__.py
│ │ │ ├── pagination.py
│ │ │ ├── permissions.py
│ │ │ ├── serializers.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── apps.py
│ │ ├── fields.py
│ │ ├── fixtures
│ │ │ └── subjects.json
│ │ ├── forms.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_video_text_image_file_content.py
│ │ │ ├── 0003_alter_content_options_alter_module_options_and_more.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
└── requirements.txt
├── Chapter16
├── Dockerfile
├── do.sh
├── docker-compose.yml
├── educa
│ ├── chat
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── consumers.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── routing.py
│ │ ├── templates
│ │ │ └── chat
│ │ │ │ └── room.html
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── courses
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── api
│ │ │ ├── __init__.py
│ │ │ ├── pagination.py
│ │ │ ├── permissions.py
│ │ │ ├── serializers.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── apps.py
│ │ ├── fields.py
│ │ ├── fixtures
│ │ │ └── subjects.json
│ │ ├── forms.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_video_text_image_file_content.py
│ │ │ ├── 0003_alter_content_options_alter_module_options_and_more.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
└── requirements.txt
├── Chapter17
├── Dockerfile
├── config
│ ├── nginx
│ │ └── default.conf.template
│ └── uwsgi
│ │ └── uwsgi.ini
├── docker-compose.yml
├── educa
│ ├── chat
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── consumers.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── routing.py
│ │ ├── templates
│ │ │ └── chat
│ │ │ │ └── room.html
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── courses
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── api
│ │ │ ├── __init__.py
│ │ │ ├── pagination.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_video_text_image_file_content.py
│ │ │ ├── 0003_alter_content_options_alter_module_options_and_more.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
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── local.py
│ │ │ └── prod.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── manage.py
│ ├── ssl
│ │ ├── educa.crt
│ │ └── educa.key
│ ├── static
│ │ ├── admin
│ │ │ ├── css
│ │ │ │ ├── autocomplete.css
│ │ │ │ ├── base.css
│ │ │ │ ├── changelists.css
│ │ │ │ ├── dark_mode.css
│ │ │ │ ├── dashboard.css
│ │ │ │ ├── fonts.css
│ │ │ │ ├── forms.css
│ │ │ │ ├── login.css
│ │ │ │ ├── nav_sidebar.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-hidelink.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
│ │ │ │ ├── admin
│ │ │ │ ├── DateTimeShortcuts.js
│ │ │ │ └── RelatedObjectLookups.js
│ │ │ │ ├── autocomplete.js
│ │ │ │ ├── calendar.js
│ │ │ │ ├── cancel.js
│ │ │ │ ├── change_form.js
│ │ │ │ ├── collapse.js
│ │ │ │ ├── core.js
│ │ │ │ ├── filters.js
│ │ │ │ ├── inlines.js
│ │ │ │ ├── jquery.init.js
│ │ │ │ ├── nav_sidebar.js
│ │ │ │ ├── popup_response.js
│ │ │ │ ├── prepopulate.js
│ │ │ │ ├── prepopulate_init.js
│ │ │ │ ├── theme.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
│ │ ├── debug_toolbar
│ │ │ ├── css
│ │ │ │ ├── print.css
│ │ │ │ └── toolbar.css
│ │ │ └── js
│ │ │ │ ├── history.js
│ │ │ │ ├── redirect.js
│ │ │ │ ├── timer.js
│ │ │ │ ├── toolbar.js
│ │ │ │ └── utils.js
│ │ ├── redisboard
│ │ │ ├── admin.css
│ │ │ └── favicon.ico
│ │ └── rest_framework
│ │ │ ├── css
│ │ │ ├── bootstrap-theme.min.css
│ │ │ ├── bootstrap-theme.min.css.map
│ │ │ ├── bootstrap-tweaks.css
│ │ │ ├── bootstrap.min.css
│ │ │ ├── bootstrap.min.css.map
│ │ │ ├── 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.5.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
├── prompts
│ └── task.md
├── requirements.txt
└── wait-for-it.sh
├── LICENSE
└── README.md
/Chapter01/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 |
16 | COPY . .
--------------------------------------------------------------------------------
/Chapter01/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | web:
3 | build: .
4 | volumes:
5 | - .:/code
6 | web_migrate:
7 | extends:
8 | service: web
9 | command: python /code/mysite/manage.py migrate
10 | web_run:
11 | extends:
12 | service: web
13 | command: python /code/mysite/manage.py runserver 0.0.0.0:8000
14 | ports:
15 | - "8000:8000"
16 | depends_on:
17 | - web_migrate
--------------------------------------------------------------------------------
/Chapter01/mysite/blog/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter01/mysite/blog/__init__.py
--------------------------------------------------------------------------------
/Chapter01/mysite/blog/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class BlogConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'blog'
7 |
--------------------------------------------------------------------------------
/Chapter01/mysite/blog/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter01/mysite/blog/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter01/mysite/blog/templates/blog/base.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 |
3 |
4 |
5 | /', views.post_detail, name='post_detail'),
11 | ]
12 |
--------------------------------------------------------------------------------
/Chapter01/mysite/mysite/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter01/mysite/mysite/__init__.py
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter01/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 |
--------------------------------------------------------------------------------
/Chapter02/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 |
16 | COPY . .
--------------------------------------------------------------------------------
/Chapter02/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | web:
3 | build: .
4 | env_file:
5 | - .env
6 | volumes:
7 | - .:/code
8 | web_migrate:
9 | extends:
10 | service: web
11 | command: python /code/mysite/manage.py migrate
12 | web_run:
13 | extends:
14 | service: web
15 | command: python /code/mysite/manage.py runserver 0.0.0.0:8000
16 | ports:
17 | - "8000:8000"
18 | depends_on:
19 | - web_migrate
--------------------------------------------------------------------------------
/Chapter02/mysite/blog/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter02/mysite/blog/__init__.py
--------------------------------------------------------------------------------
/Chapter02/mysite/blog/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class BlogConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'blog'
7 |
--------------------------------------------------------------------------------
/Chapter02/mysite/blog/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from .models import Comment
4 |
5 |
6 | class EmailPostForm(forms.Form):
7 | name = forms.CharField(max_length=25)
8 | email = forms.EmailField()
9 | to = forms.EmailField()
10 | comments = forms.CharField(
11 | required=False,
12 | widget=forms.Textarea
13 | )
14 |
15 |
16 | class CommentForm(forms.ModelForm):
17 | class Meta:
18 | model = Comment
19 | fields = ['name', 'email', 'body']
20 |
--------------------------------------------------------------------------------
/Chapter02/mysite/blog/migrations/0002_alter_post_slug.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 5.0.4 on 2024-04-04 18:44
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('blog', '0001_initial'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='post',
15 | name='slug',
16 | field=models.SlugField(max_length=250, unique_for_date='publish'),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/Chapter02/mysite/blog/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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/comment.html:
--------------------------------------------------------------------------------
1 | {% extends "blog/base.html" %}
2 |
3 | {% block title %}Add a comment{% endblock %}
4 |
5 | {% block content %}
6 | {% if comment %}
7 | Your comment has been added.
8 | Back to the post
9 | {% else %}
10 | {% include "blog/post/includes/comment_form.html" %}
11 | {% endif %}
12 | {% endblock %}
13 |
--------------------------------------------------------------------------------
/Chapter02/mysite/blog/templates/blog/post/includes/comment_form.html:
--------------------------------------------------------------------------------
1 | Add a new comment
2 |
13 |
--------------------------------------------------------------------------------
/Chapter02/mysite/blog/templates/pagination.html:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/Chapter02/mysite/blog/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter02/mysite/mysite/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter02/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | python-decouple==3.8
5 |
--------------------------------------------------------------------------------
/Chapter03/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter03/mysite/blog/__init__.py
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class BlogConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'blog'
7 |
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/migrations/0002_alter_post_slug.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 5.0.4 on 2024-04-04 18:44
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('blog', '0001_initial'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='post',
15 | name='slug',
16 | field=models.SlugField(max_length=250, unique_for_date='publish'),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/migrations/0005_trigram_ext.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 5.0.4 on 2024-04-04 18:44
2 |
3 | from django.contrib.postgres.operations import TrigramExtension
4 | from django.db import migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('blog', '0004_post_tags'),
11 | ]
12 |
13 | operations = [
14 | TrigramExtension()
15 | ]
16 |
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter03/mysite/blog/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/sitemaps.py:
--------------------------------------------------------------------------------
1 | from django.contrib.sitemaps import Sitemap
2 |
3 | from .models import Post
4 |
5 |
6 | class PostSitemap(Sitemap):
7 | changefreq = 'weekly'
8 | priority = 0.9
9 |
10 | def items(self):
11 | return Post.published.all()
12 |
13 | def lastmod(self, obj):
14 | return obj.updated
15 |
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/templates/blog/post/comment.html:
--------------------------------------------------------------------------------
1 | {% extends "blog/base.html" %}
2 |
3 | {% block title %}Add a comment{% endblock %}
4 |
5 | {% block content %}
6 | {% if comment %}
7 | Your comment has been added.
8 | Back to the post
9 | {% else %}
10 | {% include "blog/post/includes/comment_form.html" %}
11 | {% endif %}
12 | {% endblock %}
13 |
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/templates/blog/post/includes/comment_form.html:
--------------------------------------------------------------------------------
1 | Add a new comment
2 |
13 |
--------------------------------------------------------------------------------
/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/pagination.html:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter03/mysite/blog/templatetags/__init__.py
--------------------------------------------------------------------------------
/Chapter03/mysite/blog/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter03/mysite/mysite/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter03/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | python-decouple==3.8
5 | django-taggit==5.0.1
6 | Markdown==3.6
7 | psycopg==3.1.18
8 |
--------------------------------------------------------------------------------
/Chapter04/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter04/bookmarks/account/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter04/bookmarks/account/__init__.py
--------------------------------------------------------------------------------
/Chapter04/bookmarks/account/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import Profile
4 |
5 |
6 | @admin.register(Profile)
7 | class ProfileAdmin(admin.ModelAdmin):
8 | list_display = ['user', 'date_of_birth', 'photo']
9 | raw_id_fields = ['user']
10 |
--------------------------------------------------------------------------------
/Chapter04/bookmarks/account/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class AccountConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'account'
7 |
--------------------------------------------------------------------------------
/Chapter04/bookmarks/account/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter04/bookmarks/account/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter04/bookmarks/account/templates/account/dashboard.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block title %}Dashboard{% endblock %}
4 |
5 | {% block content %}
6 | Dashboard
7 |
8 | Welcome to your dashboard. You can edit your profile or change your password.
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/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 |
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 |
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 |
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 |
8 | Your account has been successfully created.
9 | Now you can log in.
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/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 |
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_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 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter04/bookmarks/account/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter04/bookmarks/bookmarks/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bookmarks.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bookmarks.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter04/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | web:
3 | build: .
4 | volumes:
5 | - .:/code
6 | web_migrate:
7 | extends:
8 | service: web
9 | command: python /code/bookmarks/manage.py migrate
10 | web_run:
11 | extends:
12 | service: web
13 | command: python /code/bookmarks/manage.py runserver 0.0.0.0:8000
14 | ports:
15 | - "8000:8000"
16 | depends_on:
17 | - web_migrate
18 |
--------------------------------------------------------------------------------
/Chapter04/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 |
--------------------------------------------------------------------------------
/Chapter05/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter05/bookmarks/account/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter05/bookmarks/account/__init__.py
--------------------------------------------------------------------------------
/Chapter05/bookmarks/account/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import Profile
4 |
5 |
6 | @admin.register(Profile)
7 | class ProfileAdmin(admin.ModelAdmin):
8 | list_display = ['user', 'date_of_birth', 'photo']
9 | raw_id_fields = ['user']
10 |
--------------------------------------------------------------------------------
/Chapter05/bookmarks/account/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class AccountConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'account'
7 |
--------------------------------------------------------------------------------
/Chapter05/bookmarks/account/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter05/bookmarks/account/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter05/bookmarks/account/templates/account/dashboard.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block title %}Dashboard{% endblock %}
4 |
5 | {% block content %}
6 | Dashboard
7 |
8 | Welcome to your dashboard. You can edit your profile or change your password.
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/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 |
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 |
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 |
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 |
8 | Your account has been successfully created.
9 | Now you can log in.
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/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 |
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_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 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter05/bookmarks/account/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter05/bookmarks/bookmarks/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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/5.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/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for bookmarks project.
3 |
4 | It exposes the WSGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bookmarks.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter05/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | web:
3 | build: .
4 | volumes:
5 | - .:/code
6 | web_migrate:
7 | extends:
8 | service: web
9 | command: python /code/bookmarks/manage.py migrate
10 | web_run:
11 | extends:
12 | service: web
13 | command: python /code/bookmarks/manage.py runserver 0.0.0.0:8000
14 | ports:
15 | - "8000:8000"
16 | depends_on:
17 | - web_migrate
--------------------------------------------------------------------------------
/Chapter05/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | python-decouple==3.8
6 | social-auth-app-django==5.4.0
7 | django-extensions==3.2.3
8 | werkzeug==3.0.2
9 | pyOpenSSL==24.1.0
10 |
--------------------------------------------------------------------------------
/Chapter06/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter06/bookmarks/account/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter06/bookmarks/account/__init__.py
--------------------------------------------------------------------------------
/Chapter06/bookmarks/account/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import Profile
4 |
5 |
6 | @admin.register(Profile)
7 | class ProfileAdmin(admin.ModelAdmin):
8 | list_display = ['user', 'date_of_birth', 'photo']
9 | raw_id_fields = ['user']
10 |
--------------------------------------------------------------------------------
/Chapter06/bookmarks/account/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class AccountConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'account'
7 |
--------------------------------------------------------------------------------
/Chapter06/bookmarks/account/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter06/bookmarks/account/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter06/bookmarks/account/models.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from django.db import models
3 |
4 |
5 | class Profile(models.Model):
6 | user = models.OneToOneField(
7 | settings.AUTH_USER_MODEL,
8 | on_delete=models.CASCADE
9 | )
10 | date_of_birth = models.DateField(blank=True, null=True)
11 | photo = models.ImageField(upload_to='users/%Y/%m/%d/', blank=True)
12 |
13 | def __str__(self):
14 | return f'Profile of {self.user.username}'
15 |
--------------------------------------------------------------------------------
/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 |
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 |
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 |
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 |
8 | Your account has been successfully created.
9 | Now you can log in.
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/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 |
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_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 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter06/bookmarks/account/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter06/bookmarks/bookmarks/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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/5.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/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/5.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/images/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter06/bookmarks/images/__init__.py
--------------------------------------------------------------------------------
/Chapter06/bookmarks/images/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import Image
4 |
5 |
6 | @admin.register(Image)
7 | class ImageAdmin(admin.ModelAdmin):
8 | list_display = ['title', 'slug', 'image', 'created']
9 | list_filter = ['created']
10 |
--------------------------------------------------------------------------------
/Chapter06/bookmarks/images/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ImagesConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'images'
7 |
--------------------------------------------------------------------------------
/Chapter06/bookmarks/images/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter06/bookmarks/images/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter06/bookmarks/images/templates/bookmarklet_launcher.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | if(!window.bookmarklet) {
3 | bookmarklet_js = document.body.appendChild(document.createElement('script'));
4 | bookmarklet_js.src = '//127.0.0.1:8000/static/js/bookmarklet.js?r='+Math.floor(Math.random()*9999999999999999);
5 | window.bookmarklet = true;
6 | }
7 | else {
8 | bookmarkletLaunch();
9 | }
10 | })();
11 |
--------------------------------------------------------------------------------
/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 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter06/bookmarks/images/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter06/bookmarks/images/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'images'
6 |
7 | urlpatterns = [
8 | path('create/', views.image_create, name='create'),
9 | path(
10 | 'detail///',
11 | views.image_detail,
12 | name='detail',
13 | ),
14 | path('like/', views.image_like, name='like'),
15 | path('', views.image_list, name='list'),
16 | ]
17 |
--------------------------------------------------------------------------------
/Chapter06/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | web:
3 | build: .
4 | volumes:
5 | - .:/code
6 | web_migrate:
7 | extends:
8 | service: web
9 | command: python /code/bookmarks/manage.py migrate
10 | web_run:
11 | extends:
12 | service: web
13 | command: python /code/bookmarks/manage.py runserver 0.0.0.0:8000
14 | ports:
15 | - "8000:8000"
16 | depends_on:
17 | - web_migrate
18 |
--------------------------------------------------------------------------------
/Chapter06/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | python-decouple==3.8
6 | social-auth-app-django==5.4.0
7 | django-extensions==3.2.3
8 | werkzeug==3.0.2
9 | pyOpenSSL==24.1.0
10 | requests==2.31.0
11 | easy-thumbnails==2.8.5
12 |
--------------------------------------------------------------------------------
/Chapter07/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter07/bookmarks/account/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter07/bookmarks/account/__init__.py
--------------------------------------------------------------------------------
/Chapter07/bookmarks/account/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import Profile
4 |
5 |
6 | @admin.register(Profile)
7 | class ProfileAdmin(admin.ModelAdmin):
8 | list_display = ['user', 'date_of_birth', 'photo']
9 | raw_id_fields = ['user']
10 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/account/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class AccountConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'account'
7 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/account/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter07/bookmarks/account/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter07/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 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/Chapter07/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 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter07/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 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter07/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 |
8 | Your account has been successfully created.
9 | Now you can log in.
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/Chapter07/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 |
--------------------------------------------------------------------------------
/Chapter07/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 |
--------------------------------------------------------------------------------
/Chapter07/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 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter07/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 |
--------------------------------------------------------------------------------
/Chapter07/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 |
--------------------------------------------------------------------------------
/Chapter07/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 |
--------------------------------------------------------------------------------
/Chapter07/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 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/account/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/actions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter07/bookmarks/actions/__init__.py
--------------------------------------------------------------------------------
/Chapter07/bookmarks/actions/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import Action
4 |
5 |
6 | @admin.register(Action)
7 | class ActionAdmin(admin.ModelAdmin):
8 | list_display = ['user', 'verb', 'target', 'created']
9 | list_filter = ['created']
10 | search_fields = ['verb']
11 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/actions/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ActionsConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'actions'
7 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/actions/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter07/bookmarks/actions/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter07/bookmarks/actions/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/actions/views.py:
--------------------------------------------------------------------------------
1 | # Create your views here.
2 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/bookmarks/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter07/bookmarks/bookmarks/__init__.py
--------------------------------------------------------------------------------
/Chapter07/bookmarks/bookmarks/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for bookmarks project.
3 |
4 | It exposes the ASGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bookmarks.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter07/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/5.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 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/images/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter07/bookmarks/images/__init__.py
--------------------------------------------------------------------------------
/Chapter07/bookmarks/images/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import Image
4 |
5 |
6 | @admin.register(Image)
7 | class ImageAdmin(admin.ModelAdmin):
8 | list_display = ['title', 'slug', 'image', 'created']
9 | list_filter = ['created']
10 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/images/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ImagesConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'images'
7 |
8 | def ready(self):
9 | # import signal handlers
10 | import images.signals
11 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/images/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter07/bookmarks/images/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter07/bookmarks/images/signals.py:
--------------------------------------------------------------------------------
1 | from django.db.models.signals import m2m_changed
2 | from django.dispatch import receiver
3 |
4 | from .models import Image
5 |
6 |
7 | @receiver(m2m_changed, sender=Image.users_like.through)
8 | def users_like_changed(sender, instance, **kwargs):
9 | instance.total_likes = instance.users_like.count()
10 | instance.save()
11 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/images/templates/bookmarklet_launcher.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | if(!window.bookmarklet) {
3 | bookmarklet_js = document.body.appendChild(document.createElement('script'));
4 | bookmarklet_js.src = '//127.0.0.1:8000/static/js/bookmarklet.js?r='+Math.floor(Math.random()*9999999999999999);
5 | window.bookmarklet = true;
6 | }
7 | else {
8 | bookmarkletLaunch();
9 | }
10 | })();
11 |
--------------------------------------------------------------------------------
/Chapter07/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 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter07/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 | -
10 |
11 | {{ image.title }}
12 |
13 |
14 | {% endfor %}
15 |
16 | {% endblock %}
17 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/images/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter07/bookmarks/images/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'images'
6 |
7 | urlpatterns = [
8 | path('create/', views.image_create, name='create'),
9 | path(
10 | 'detail///',
11 | views.image_detail,
12 | name='detail',
13 | ),
14 | path('like/', views.image_like, name='like'),
15 | path('', views.image_list, name='list'),
16 | path('ranking/', views.image_ranking, name='ranking'),
17 | ]
18 |
--------------------------------------------------------------------------------
/Chapter07/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | python-decouple==3.8
6 | social-auth-app-django==5.4.0
7 | django-extensions==3.2.3
8 | werkzeug==3.0.2
9 | pyOpenSSL==24.1.0
10 | requests==2.31.0
11 | easy-thumbnails==2.8.5
12 | django-debug-toolbar==4.3.0
13 | redis==5.0.4
14 |
--------------------------------------------------------------------------------
/Chapter08/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter08/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | web:
3 | build: .
4 | volumes:
5 | - .:/code
6 | web_migrate:
7 | extends:
8 | service: web
9 | command: python /code/myshop/manage.py migrate
10 | web_run:
11 | extends:
12 | service: web
13 | command: python /code/myshop/manage.py runserver 0.0.0.0:8000
14 | ports:
15 | - "8000:8000"
16 | depends_on:
17 | - web_migrate
18 |
--------------------------------------------------------------------------------
/Chapter08/myshop/cart/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter08/myshop/cart/__init__.py
--------------------------------------------------------------------------------
/Chapter08/myshop/cart/admin.py:
--------------------------------------------------------------------------------
1 |
2 | # Register your models here.
3 |
--------------------------------------------------------------------------------
/Chapter08/myshop/cart/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CartConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'cart'
7 |
--------------------------------------------------------------------------------
/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 | PRODUCT_QUANTITY_CHOICES = [(i, str(i)) for i in range(1, 21)]
4 |
5 |
6 | class CartAddProductForm(forms.Form):
7 | quantity = forms.TypedChoiceField(
8 | choices=PRODUCT_QUANTITY_CHOICES,
9 | coerce=int
10 | )
11 | override = forms.BooleanField(
12 | required=False,
13 | initial=False,
14 | widget=forms.HiddenInput
15 | )
16 |
--------------------------------------------------------------------------------
/Chapter08/myshop/cart/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter08/myshop/cart/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter08/myshop/cart/models.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your models here.
3 |
--------------------------------------------------------------------------------
/Chapter08/myshop/cart/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter08/myshop/cart/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'cart'
6 |
7 | urlpatterns = [
8 | path('', views.cart_detail, name='cart_detail'),
9 | path('add//', views.cart_add, name='cart_add'),
10 | path(
11 | 'remove//',
12 | views.cart_remove,
13 | name='cart_remove',
14 | ),
15 | ]
16 |
--------------------------------------------------------------------------------
/Chapter08/myshop/myshop/__init__.py:
--------------------------------------------------------------------------------
1 | # import celery
2 | from .celery import app as celery_app
3 |
4 | __all__ = ['celery_app']
5 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter08/myshop/myshop/celery.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from celery import Celery
4 |
5 | # set the default Django settings module for the 'celery' program.
6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
7 |
8 | app = Celery('myshop')
9 | app.config_from_object('django.conf:settings', namespace='CELERY')
10 | app.autodiscover_tasks()
11 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter08/myshop/orders/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter08/myshop/orders/__init__.py
--------------------------------------------------------------------------------
/Chapter08/myshop/orders/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class OrdersConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'orders'
7 |
--------------------------------------------------------------------------------
/Chapter08/myshop/orders/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from .models import Order
4 |
5 |
6 | class OrderCreateForm(forms.ModelForm):
7 | class Meta:
8 | model = Order
9 | fields = [
10 | 'first_name',
11 | 'last_name',
12 | 'email',
13 | 'address',
14 | 'postal_code',
15 | 'city',
16 | ]
17 |
--------------------------------------------------------------------------------
/Chapter08/myshop/orders/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter08/myshop/orders/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 |
6 | app_name = 'orders'
7 |
8 | urlpatterns = [
9 | path('create/', views.order_create, name='order_create'),
10 | ]
11 |
--------------------------------------------------------------------------------
/Chapter08/myshop/shop/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter08/myshop/shop/__init__.py
--------------------------------------------------------------------------------
/Chapter08/myshop/shop/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ShopConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'shop'
7 |
--------------------------------------------------------------------------------
/Chapter08/myshop/shop/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter08/myshop/shop/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter08/myshop/shop/static/img/no_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter08/myshop/shop/static/img/no_image.png
--------------------------------------------------------------------------------
/Chapter08/myshop/shop/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter08/myshop/shop/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'shop'
6 |
7 | urlpatterns = [
8 | path('', views.product_list, name='product_list'),
9 | path(
10 | '/',
11 | views.product_list,
12 | name='product_list_by_category',
13 | ),
14 | path(
15 | '//',
16 | views.product_detail,
17 | name='product_detail',
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/Chapter08/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | flower==2.0.1
6 | celery==5.4.0
7 |
--------------------------------------------------------------------------------
/Chapter09/myshop/cart/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/cart/__init__.py
--------------------------------------------------------------------------------
/Chapter09/myshop/cart/admin.py:
--------------------------------------------------------------------------------
1 |
2 | # Register your models here.
3 |
--------------------------------------------------------------------------------
/Chapter09/myshop/cart/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CartConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'cart'
7 |
--------------------------------------------------------------------------------
/Chapter09/myshop/cart/context_processors.py:
--------------------------------------------------------------------------------
1 | from .cart import Cart
2 |
3 |
4 | def cart(request):
5 | return {'cart': Cart(request)}
6 |
--------------------------------------------------------------------------------
/Chapter09/myshop/cart/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | PRODUCT_QUANTITY_CHOICES = [(i, str(i)) for i in range(1, 21)]
4 |
5 |
6 | class CartAddProductForm(forms.Form):
7 | quantity = forms.TypedChoiceField(
8 | choices=PRODUCT_QUANTITY_CHOICES,
9 | coerce=int
10 | )
11 | override = forms.BooleanField(
12 | required=False,
13 | initial=False,
14 | widget=forms.HiddenInput
15 | )
16 |
--------------------------------------------------------------------------------
/Chapter09/myshop/cart/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/cart/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter09/myshop/cart/models.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your models here.
3 |
--------------------------------------------------------------------------------
/Chapter09/myshop/cart/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter09/myshop/cart/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'cart'
6 |
7 | urlpatterns = [
8 | path('', views.cart_detail, name='cart_detail'),
9 | path('add//', views.cart_add, name='cart_add'),
10 | path(
11 | 'remove//',
12 | views.cart_remove,
13 | name='cart_remove',
14 | ),
15 | ]
16 |
--------------------------------------------------------------------------------
/Chapter09/myshop/myshop/__init__.py:
--------------------------------------------------------------------------------
1 | # import celery
2 | from .celery import app as celery_app
3 |
4 | __all__ = ['celery_app']
5 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter09/myshop/myshop/celery.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from celery import Celery
4 |
5 | # set the default Django settings module for the 'celery' program.
6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
7 |
8 | app = Celery('myshop')
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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter09/myshop/orders/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/orders/__init__.py
--------------------------------------------------------------------------------
/Chapter09/myshop/orders/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class OrdersConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'orders'
7 |
--------------------------------------------------------------------------------
/Chapter09/myshop/orders/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from .models import Order
4 |
5 |
6 | class OrderCreateForm(forms.ModelForm):
7 | class Meta:
8 | model = Order
9 | fields = [
10 | 'first_name',
11 | 'last_name',
12 | 'email',
13 | 'address',
14 | 'postal_code',
15 | 'city',
16 | ]
17 |
--------------------------------------------------------------------------------
/Chapter09/myshop/orders/migrations/0002_order_stripe_id.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 5.0.4 on 2024-04-04 18:44
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='stripe_id',
16 | field=models.CharField(blank=True, max_length=250),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/Chapter09/myshop/orders/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/orders/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter09/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 |
--------------------------------------------------------------------------------
/Chapter09/myshop/orders/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter09/myshop/orders/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 |
6 | app_name = 'orders'
7 |
8 |
9 | urlpatterns = [
10 | path('create/', views.order_create, name='order_create'),
11 | path(
12 | 'admin/order//',
13 | views.admin_order_detail,
14 | name='admin_order_detail',
15 | ),
16 | path(
17 | 'admin/order//pdf/',
18 | views.admin_order_pdf,
19 | name='admin_order_pdf',
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/Chapter09/myshop/payment/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/payment/__init__.py
--------------------------------------------------------------------------------
/Chapter09/myshop/payment/admin.py:
--------------------------------------------------------------------------------
1 |
2 | # Register your models here.
3 |
--------------------------------------------------------------------------------
/Chapter09/myshop/payment/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class PaymentConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'payment'
7 |
--------------------------------------------------------------------------------
/Chapter09/myshop/payment/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/payment/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter09/myshop/payment/models.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your models here.
3 |
--------------------------------------------------------------------------------
/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/completed.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 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter09/myshop/payment/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views, webhooks
4 |
5 | app_name = 'payment'
6 |
7 | urlpatterns = [
8 | path('process/', views.payment_process, name='process'),
9 | path('completed/', views.payment_completed, name='completed'),
10 | path('canceled/', views.payment_canceled, name='canceled'),
11 | path('webhook/', webhooks.stripe_webhook, name='stripe-webhook'),
12 | ]
13 |
--------------------------------------------------------------------------------
/Chapter09/myshop/shop/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/shop/__init__.py
--------------------------------------------------------------------------------
/Chapter09/myshop/shop/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ShopConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'shop'
7 |
--------------------------------------------------------------------------------
/Chapter09/myshop/shop/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/shop/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter09/myshop/shop/static/img/no_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/shop/static/img/no_image.png
--------------------------------------------------------------------------------
/Chapter09/myshop/shop/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter09/myshop/shop/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'shop'
6 |
7 | urlpatterns = [
8 | path('', views.product_list, name='product_list'),
9 | path(
10 | '/',
11 | views.product_list,
12 | name='product_list_by_category',
13 | ),
14 | path(
15 | '//',
16 | views.product_detail,
17 | name='product_detail',
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/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-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/static/admin/fonts/Roboto-Bold-webfont.woff
--------------------------------------------------------------------------------
/Chapter09/myshop/static/admin/fonts/Roboto-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/static/admin/fonts/Roboto-Light-webfont.woff
--------------------------------------------------------------------------------
/Chapter09/myshop/static/admin/fonts/Roboto-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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 |
4 |
--------------------------------------------------------------------------------
/Chapter09/myshop/static/admin/img/icon-changelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter09/myshop/static/admin/img/icon-deletelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter09/myshop/static/admin/img/icon-yes.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter09/myshop/static/admin/img/search.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter09/myshop/static/admin/img/tooltag-add.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter09/myshop/static/admin/img/tooltag-arrowright.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter09/myshop/static/admin/js/jquery.init.js:
--------------------------------------------------------------------------------
1 | /*global jQuery:false*/
2 | 'use strict';
3 | /* Puts the included jQuery into our own namespace using noConflict and passing
4 | * it 'true'. This ensures that the included jQuery doesn't pollute the global
5 | * namespace (i.e. this preserves pre-existing values for both window.$ and
6 | * window.jQuery).
7 | */
8 | window.django = {jQuery: jQuery.noConflict(true)};
9 |
--------------------------------------------------------------------------------
/Chapter09/myshop/static/img/no_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter09/myshop/static/img/no_image.png
--------------------------------------------------------------------------------
/Chapter09/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | flower==2.0.1
6 | celery==5.4.0
7 | stripe==9.3.0
8 | python-decouple==3.8
9 | WeasyPrint==61.2
--------------------------------------------------------------------------------
/Chapter10/myshop/cart/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/cart/__init__.py
--------------------------------------------------------------------------------
/Chapter10/myshop/cart/admin.py:
--------------------------------------------------------------------------------
1 |
2 | # Register your models here.
3 |
--------------------------------------------------------------------------------
/Chapter10/myshop/cart/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CartConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'cart'
7 |
--------------------------------------------------------------------------------
/Chapter10/myshop/cart/context_processors.py:
--------------------------------------------------------------------------------
1 | from .cart import Cart
2 |
3 |
4 | def cart(request):
5 | return {'cart': Cart(request)}
6 |
--------------------------------------------------------------------------------
/Chapter10/myshop/cart/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | PRODUCT_QUANTITY_CHOICES = [(i, str(i)) for i in range(1, 21)]
4 |
5 |
6 | class CartAddProductForm(forms.Form):
7 | quantity = forms.TypedChoiceField(
8 | choices=PRODUCT_QUANTITY_CHOICES,
9 | coerce=int
10 | )
11 | override = forms.BooleanField(
12 | required=False,
13 | initial=False,
14 | widget=forms.HiddenInput
15 | )
16 |
--------------------------------------------------------------------------------
/Chapter10/myshop/cart/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/cart/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter10/myshop/cart/models.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your models here.
3 |
--------------------------------------------------------------------------------
/Chapter10/myshop/cart/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter10/myshop/cart/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'cart'
6 |
7 | urlpatterns = [
8 | path('', views.cart_detail, name='cart_detail'),
9 | path('add//', views.cart_add, name='cart_add'),
10 | path(
11 | 'remove//',
12 | views.cart_remove,
13 | name='cart_remove',
14 | ),
15 | ]
16 |
--------------------------------------------------------------------------------
/Chapter10/myshop/coupons/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/coupons/__init__.py
--------------------------------------------------------------------------------
/Chapter10/myshop/coupons/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import Coupon
4 |
5 |
6 | @admin.register(Coupon)
7 | class CouponAdmin(admin.ModelAdmin):
8 | list_display = [
9 | 'code',
10 | 'valid_from',
11 | 'valid_to',
12 | 'discount',
13 | 'active',
14 | ]
15 | list_filter = ['active', 'valid_from', 'valid_to']
16 | search_fields = ['code']
17 |
--------------------------------------------------------------------------------
/Chapter10/myshop/coupons/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CouponsConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'coupons'
7 |
--------------------------------------------------------------------------------
/Chapter10/myshop/coupons/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 |
4 | class CouponApplyForm(forms.Form):
5 | code = forms.CharField()
6 |
--------------------------------------------------------------------------------
/Chapter10/myshop/coupons/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/coupons/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter10/myshop/coupons/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter10/myshop/coupons/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'coupons'
6 |
7 | urlpatterns = [
8 | path('apply/', views.coupon_apply, name='apply'),
9 | ]
10 |
--------------------------------------------------------------------------------
/Chapter10/myshop/myshop/__init__.py:
--------------------------------------------------------------------------------
1 | # import celery
2 | from .celery import app as celery_app
3 |
4 | __all__ = ['celery_app']
5 |
--------------------------------------------------------------------------------
/Chapter10/myshop/myshop/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for myshop project.
3 |
4 | It exposes the ASGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter10/myshop/myshop/celery.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from celery import Celery
4 |
5 | # set the default Django settings module for the 'celery' program.
6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
7 |
8 | app = Celery('myshop')
9 | app.config_from_object('django.conf:settings', namespace='CELERY')
10 | app.autodiscover_tasks()
11 |
--------------------------------------------------------------------------------
/Chapter10/myshop/myshop/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for myshop project.
3 |
4 | It exposes the WSGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter10/myshop/orders/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/orders/__init__.py
--------------------------------------------------------------------------------
/Chapter10/myshop/orders/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class OrdersConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'orders'
7 |
--------------------------------------------------------------------------------
/Chapter10/myshop/orders/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from .models import Order
4 |
5 |
6 | class OrderCreateForm(forms.ModelForm):
7 | class Meta:
8 | model = Order
9 | fields = [
10 | 'first_name',
11 | 'last_name',
12 | 'email',
13 | 'address',
14 | 'postal_code',
15 | 'city',
16 | ]
17 |
--------------------------------------------------------------------------------
/Chapter10/myshop/orders/migrations/0002_order_stripe_id.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 5.0.4 on 2024-04-04 18:44
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='stripe_id',
16 | field=models.CharField(blank=True, max_length=250),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/Chapter10/myshop/orders/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/orders/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter10/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 |
--------------------------------------------------------------------------------
/Chapter10/myshop/orders/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter10/myshop/orders/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 |
6 | app_name = 'orders'
7 |
8 |
9 | urlpatterns = [
10 | path('create/', views.order_create, name='order_create'),
11 | path(
12 | 'admin/order//',
13 | views.admin_order_detail,
14 | name='admin_order_detail',
15 | ),
16 | path(
17 | 'admin/order//pdf/',
18 | views.admin_order_pdf,
19 | name='admin_order_pdf',
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/Chapter10/myshop/payment/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/payment/__init__.py
--------------------------------------------------------------------------------
/Chapter10/myshop/payment/admin.py:
--------------------------------------------------------------------------------
1 |
2 | # Register your models here.
3 |
--------------------------------------------------------------------------------
/Chapter10/myshop/payment/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class PaymentConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'payment'
7 |
--------------------------------------------------------------------------------
/Chapter10/myshop/payment/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/payment/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter10/myshop/payment/models.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your models here.
3 |
--------------------------------------------------------------------------------
/Chapter10/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 |
--------------------------------------------------------------------------------
/Chapter10/myshop/payment/templates/payment/completed.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 |
--------------------------------------------------------------------------------
/Chapter10/myshop/payment/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter10/myshop/payment/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views, webhooks
4 |
5 | app_name = 'payment'
6 |
7 | urlpatterns = [
8 | path('process/', views.payment_process, name='process'),
9 | path('completed/', views.payment_completed, name='completed'),
10 | path('canceled/', views.payment_canceled, name='canceled'),
11 | path('webhook/', webhooks.stripe_webhook, name='stripe-webhook'),
12 | ]
13 |
--------------------------------------------------------------------------------
/Chapter10/myshop/shop/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/shop/__init__.py
--------------------------------------------------------------------------------
/Chapter10/myshop/shop/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ShopConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'shop'
7 |
--------------------------------------------------------------------------------
/Chapter10/myshop/shop/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/shop/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter10/myshop/shop/static/img/no_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/shop/static/img/no_image.png
--------------------------------------------------------------------------------
/Chapter10/myshop/shop/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter10/myshop/shop/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'shop'
6 |
7 | urlpatterns = [
8 | path('', views.product_list, name='product_list'),
9 | path(
10 | '/',
11 | views.product_list,
12 | name='product_list_by_category',
13 | ),
14 | path(
15 | '//',
16 | views.product_detail,
17 | name='product_detail',
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/Chapter10/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 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/fonts/Roboto-Bold-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/static/admin/fonts/Roboto-Bold-webfont.woff
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/fonts/Roboto-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/static/admin/fonts/Roboto-Light-webfont.woff
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/fonts/Roboto-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/static/admin/fonts/Roboto-Regular-webfont.woff
--------------------------------------------------------------------------------
/Chapter10/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 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/img/icon-addlink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/img/icon-changelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/img/icon-deletelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/img/icon-yes.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/img/search.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/img/tooltag-add.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/img/tooltag-arrowright.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/admin/js/jquery.init.js:
--------------------------------------------------------------------------------
1 | /*global jQuery:false*/
2 | 'use strict';
3 | /* Puts the included jQuery into our own namespace using noConflict and passing
4 | * it 'true'. This ensures that the included jQuery doesn't pollute the global
5 | * namespace (i.e. this preserves pre-existing values for both window.$ and
6 | * window.jQuery).
7 | */
8 | window.django = {jQuery: jQuery.noConflict(true)};
9 |
--------------------------------------------------------------------------------
/Chapter10/myshop/static/img/no_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter10/myshop/static/img/no_image.png
--------------------------------------------------------------------------------
/Chapter10/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | flower==2.0.1
6 | celery==5.4.0
7 | stripe==9.3.0
8 | python-decouple==3.8
9 | WeasyPrint==61.2
10 | redis==5.0.4
11 |
--------------------------------------------------------------------------------
/Chapter11/myshop/cart/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/cart/__init__.py
--------------------------------------------------------------------------------
/Chapter11/myshop/cart/admin.py:
--------------------------------------------------------------------------------
1 |
2 | # Register your models here.
3 |
--------------------------------------------------------------------------------
/Chapter11/myshop/cart/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CartConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'cart'
7 |
--------------------------------------------------------------------------------
/Chapter11/myshop/cart/context_processors.py:
--------------------------------------------------------------------------------
1 | from .cart import Cart
2 |
3 |
4 | def cart(request):
5 | return {'cart': Cart(request)}
6 |
--------------------------------------------------------------------------------
/Chapter11/myshop/cart/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/cart/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter11/myshop/cart/models.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your models here.
3 |
--------------------------------------------------------------------------------
/Chapter11/myshop/cart/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter11/myshop/cart/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'cart'
6 |
7 | urlpatterns = [
8 | path('', views.cart_detail, name='cart_detail'),
9 | path('add//', views.cart_add, name='cart_add'),
10 | path(
11 | 'remove//',
12 | views.cart_remove,
13 | name='cart_remove',
14 | ),
15 | ]
16 |
--------------------------------------------------------------------------------
/Chapter11/myshop/coupons/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/coupons/__init__.py
--------------------------------------------------------------------------------
/Chapter11/myshop/coupons/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import Coupon
4 |
5 |
6 | @admin.register(Coupon)
7 | class CouponAdmin(admin.ModelAdmin):
8 | list_display = [
9 | 'code',
10 | 'valid_from',
11 | 'valid_to',
12 | 'discount',
13 | 'active',
14 | ]
15 | list_filter = ['active', 'valid_from', 'valid_to']
16 | search_fields = ['code']
17 |
--------------------------------------------------------------------------------
/Chapter11/myshop/coupons/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CouponsConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'coupons'
7 |
--------------------------------------------------------------------------------
/Chapter11/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 |
--------------------------------------------------------------------------------
/Chapter11/myshop/coupons/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/coupons/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter11/myshop/coupons/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter11/myshop/coupons/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'coupons'
6 |
7 | urlpatterns = [
8 | path('apply/', views.coupon_apply, name='apply'),
9 | ]
10 |
--------------------------------------------------------------------------------
/Chapter11/myshop/myshop/__init__.py:
--------------------------------------------------------------------------------
1 | # import celery
2 | from .celery import app as celery_app
3 |
4 | __all__ = ['celery_app']
5 |
--------------------------------------------------------------------------------
/Chapter11/myshop/myshop/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for myshop project.
3 |
4 | It exposes the ASGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter11/myshop/myshop/celery.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from celery import Celery
4 |
5 | # set the default Django settings module for the 'celery' program.
6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
7 |
8 | app = Celery('myshop')
9 | app.config_from_object('django.conf:settings', namespace='CELERY')
10 | app.autodiscover_tasks()
11 |
--------------------------------------------------------------------------------
/Chapter11/myshop/myshop/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for myshop project.
3 |
4 | It exposes the WSGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myshop.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter11/myshop/orders/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/orders/__init__.py
--------------------------------------------------------------------------------
/Chapter11/myshop/orders/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class OrdersConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'orders'
7 |
--------------------------------------------------------------------------------
/Chapter11/myshop/orders/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from localflavor.us.forms import USZipCodeField
3 |
4 | from .models import Order
5 |
6 |
7 | class OrderCreateForm(forms.ModelForm):
8 | postal_code = USZipCodeField()
9 |
10 | class Meta:
11 | model = Order
12 | fields = [
13 | 'first_name',
14 | 'last_name',
15 | 'email',
16 | 'address',
17 | 'postal_code',
18 | 'city',
19 | ]
20 |
--------------------------------------------------------------------------------
/Chapter11/myshop/orders/migrations/0002_order_stripe_id.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 5.0.4 on 2024-04-04 18:44
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='stripe_id',
16 | field=models.CharField(blank=True, max_length=250),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/Chapter11/myshop/orders/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/orders/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter11/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 |
--------------------------------------------------------------------------------
/Chapter11/myshop/orders/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter11/myshop/payment/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/payment/__init__.py
--------------------------------------------------------------------------------
/Chapter11/myshop/payment/admin.py:
--------------------------------------------------------------------------------
1 |
2 | # Register your models here.
3 |
--------------------------------------------------------------------------------
/Chapter11/myshop/payment/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class PaymentConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'payment'
7 |
--------------------------------------------------------------------------------
/Chapter11/myshop/payment/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/payment/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter11/myshop/payment/models.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your models here.
3 |
--------------------------------------------------------------------------------
/Chapter11/myshop/payment/templates/payment/canceled.html:
--------------------------------------------------------------------------------
1 | {% extends "shop/base.html" %}
2 | {% load i18n %}
3 |
4 | {% block title %}{% translate "Payment canceled" %}{% endblock %}
5 |
6 | {% block content %}
7 | {% translate "Your payment has not been processed" %}
8 | {% translate "There was a problem processing your payment." %}
9 | {% endblock %}
10 |
--------------------------------------------------------------------------------
/Chapter11/myshop/payment/templates/payment/completed.html:
--------------------------------------------------------------------------------
1 | {% extends "shop/base.html" %}
2 | {% load i18n %}
3 |
4 | {% block title %}{% translate "Payment successful" %}{% endblock %}
5 |
6 | {% block content %}
7 | {% translate "Your payment was successful" %}
8 | {% translate "Your payment has been processed successfully." %}
9 | {% endblock %}
10 |
--------------------------------------------------------------------------------
/Chapter11/myshop/payment/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter11/myshop/payment/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 | from django.utils.translation import gettext_lazy as _
3 |
4 | from . import views
5 |
6 | app_name = 'payment'
7 |
8 | urlpatterns = [
9 | path(_('process/'), views.payment_process, name='process'),
10 | path(_('completed/'), views.payment_completed, name='completed'),
11 | path(_('canceled/'), views.payment_canceled, name='canceled'),
12 | ]
13 |
--------------------------------------------------------------------------------
/Chapter11/myshop/shop/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/shop/__init__.py
--------------------------------------------------------------------------------
/Chapter11/myshop/shop/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ShopConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'shop'
7 |
--------------------------------------------------------------------------------
/Chapter11/myshop/shop/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/shop/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter11/myshop/shop/static/img/no_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/shop/static/img/no_image.png
--------------------------------------------------------------------------------
/Chapter11/myshop/shop/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter11/myshop/shop/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'shop'
6 |
7 | urlpatterns = [
8 | path('', views.product_list, name='product_list'),
9 | path(
10 | '/',
11 | views.product_list,
12 | name='product_list_by_category',
13 | ),
14 | path(
15 | '//',
16 | views.product_detail,
17 | name='product_detail',
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/Chapter11/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 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/fonts/Roboto-Bold-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/static/admin/fonts/Roboto-Bold-webfont.woff
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/fonts/Roboto-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/static/admin/fonts/Roboto-Light-webfont.woff
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/fonts/Roboto-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/static/admin/fonts/Roboto-Regular-webfont.woff
--------------------------------------------------------------------------------
/Chapter11/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 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/img/icon-addlink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/img/icon-changelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/img/icon-deletelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/img/icon-yes.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/img/icon_searchbox_rosetta.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/static/admin/img/icon_searchbox_rosetta.png
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/img/search.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/img/tooltag-add.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/img/tooltag-arrowright.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/admin/js/jquery.init.js:
--------------------------------------------------------------------------------
1 | /*global jQuery:false*/
2 | 'use strict';
3 | /* Puts the included jQuery into our own namespace using noConflict and passing
4 | * it 'true'. This ensures that the included jQuery doesn't pollute the global
5 | * namespace (i.e. this preserves pre-existing values for both window.$ and
6 | * window.jQuery).
7 | */
8 | window.django = {jQuery: jQuery.noConflict(true)};
9 |
--------------------------------------------------------------------------------
/Chapter11/myshop/static/img/no_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter11/myshop/static/img/no_image.png
--------------------------------------------------------------------------------
/Chapter11/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | flower==2.0.1
6 | celery==5.4.0
7 | stripe==9.3.0
8 | python-decouple==3.8
9 | WeasyPrint==61.2
10 | redis==5.0.4
11 | django-rosetta==0.10.0
12 | django-parler==2.3
13 | django-localflavor==4.0
14 |
--------------------------------------------------------------------------------
/Chapter12/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter12/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | web:
3 | build: .
4 | volumes:
5 | - .:/code
6 | web_migrate:
7 | extends:
8 | service: web
9 | command: python /code/educa/manage.py migrate
10 | web_run:
11 | extends:
12 | service: web
13 | command: python /code/educa/manage.py runserver 0.0.0.0:8000
14 | ports:
15 | - "8000:8000"
16 | depends_on:
17 | - web_migrate
18 |
--------------------------------------------------------------------------------
/Chapter12/educa/courses/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter12/educa/courses/__init__.py
--------------------------------------------------------------------------------
/Chapter12/educa/courses/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CoursesConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'courses'
7 |
--------------------------------------------------------------------------------
/Chapter12/educa/courses/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter12/educa/courses/migrations/__init__.py
--------------------------------------------------------------------------------
/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 |
9 | You have been successfully logged out.
10 | You can log-in again.
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter12/educa/courses/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter12/educa/courses/views.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your views here.
3 |
--------------------------------------------------------------------------------
/Chapter12/educa/educa/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter12/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 |
--------------------------------------------------------------------------------
/Chapter13/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter13/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | web:
3 | build: .
4 | volumes:
5 | - .:/code
6 | web_migrate:
7 | extends:
8 | service: web
9 | command: python /code/educa/manage.py migrate
10 | web_run:
11 | extends:
12 | service: web
13 | command: python /code/educa/manage.py runserver 0.0.0.0:8000
14 | ports:
15 | - "8000:8000"
16 | depends_on:
17 | - web_migrate
18 |
--------------------------------------------------------------------------------
/Chapter13/educa/courses/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter13/educa/courses/__init__.py
--------------------------------------------------------------------------------
/Chapter13/educa/courses/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CoursesConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'courses'
7 |
--------------------------------------------------------------------------------
/Chapter13/educa/courses/forms.py:
--------------------------------------------------------------------------------
1 | from django.forms.models import inlineformset_factory
2 |
3 | from .models import Course, Module
4 |
5 | ModuleFormSet = inlineformset_factory(
6 | Course,
7 | Module,
8 | fields=['title', 'description'],
9 | extra=2,
10 | can_delete=True,
11 | )
12 |
--------------------------------------------------------------------------------
/Chapter13/educa/courses/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter13/educa/courses/migrations/__init__.py
--------------------------------------------------------------------------------
/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 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/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 |
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 |
9 | You have been successfully logged out.
10 | You can log-in again.
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter13/educa/courses/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter13/educa/courses/templatetags/__init__.py
--------------------------------------------------------------------------------
/Chapter13/educa/courses/templatetags/course.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 | register = template.Library()
4 |
5 |
6 | @register.filter
7 | def model_name(obj):
8 | try:
9 | return obj._meta.model_name
10 | except AttributeError:
11 | return None
12 |
--------------------------------------------------------------------------------
/Chapter13/educa/courses/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter13/educa/educa/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter13/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | django-braces==1.15.0
6 |
--------------------------------------------------------------------------------
/Chapter14/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter14/educa/courses/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter14/educa/courses/__init__.py
--------------------------------------------------------------------------------
/Chapter14/educa/courses/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CoursesConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'courses'
7 |
--------------------------------------------------------------------------------
/Chapter14/educa/courses/forms.py:
--------------------------------------------------------------------------------
1 | from django.forms.models import inlineformset_factory
2 |
3 | from .models import Course, Module
4 |
5 | ModuleFormSet = inlineformset_factory(
6 | Course,
7 | Module,
8 | fields=['title', 'description'],
9 | extra=2,
10 | can_delete=True,
11 | )
12 |
--------------------------------------------------------------------------------
/Chapter14/educa/courses/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter14/educa/courses/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter14/educa/courses/templates/courses/content/file.html:
--------------------------------------------------------------------------------
1 |
2 | Download file
3 |
4 |
--------------------------------------------------------------------------------
/Chapter14/educa/courses/templates/courses/content/image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/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 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/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 |
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 |
9 | You have been successfully logged out.
10 | You can log-in again.
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter14/educa/courses/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter14/educa/courses/templatetags/__init__.py
--------------------------------------------------------------------------------
/Chapter14/educa/courses/templatetags/course.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 | register = template.Library()
4 |
5 |
6 | @register.filter
7 | def model_name(obj):
8 | try:
9 | return obj._meta.model_name
10 | except AttributeError:
11 | return None
12 |
--------------------------------------------------------------------------------
/Chapter14/educa/courses/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter14/educa/educa/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter14/educa/educa/__init__.py
--------------------------------------------------------------------------------
/Chapter14/educa/educa/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for educa project.
3 |
4 | It exposes the ASGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/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
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter14/educa/students/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter14/educa/students/__init__.py
--------------------------------------------------------------------------------
/Chapter14/educa/students/admin.py:
--------------------------------------------------------------------------------
1 |
2 | # Register your models here.
3 |
--------------------------------------------------------------------------------
/Chapter14/educa/students/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class StudentsConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'students'
7 |
--------------------------------------------------------------------------------
/Chapter14/educa/students/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from courses.models import Course
4 |
5 |
6 | class CourseEnrollForm(forms.Form):
7 | course = forms.ModelChoiceField(
8 | queryset=Course.objects.none(),
9 | widget=forms.HiddenInput
10 | )
11 |
12 | def __init__(self, *args, **kwargs):
13 | super(CourseEnrollForm, self).__init__(*args, **kwargs)
14 | self.fields['course'].queryset = Course.objects.all()
15 |
--------------------------------------------------------------------------------
/Chapter14/educa/students/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter14/educa/students/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter14/educa/students/models.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your models here.
3 |
--------------------------------------------------------------------------------
/Chapter14/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 |
18 |
19 | {% endblock %}
20 |
--------------------------------------------------------------------------------
/Chapter14/educa/students/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter14/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | django-braces==1.15.0
6 | django-embed-video==1.4.9
7 | pymemcache==4.0.0
8 | django-debug-toolbar==4.3.0
9 | redis==5.0.4
10 | django-redisboard==8.4.0
11 |
--------------------------------------------------------------------------------
/Chapter15/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter15/educa/courses/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter15/educa/courses/__init__.py
--------------------------------------------------------------------------------
/Chapter15/educa/courses/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter15/educa/courses/api/__init__.py
--------------------------------------------------------------------------------
/Chapter15/educa/courses/api/pagination.py:
--------------------------------------------------------------------------------
1 | from rest_framework.pagination import PageNumberPagination
2 |
3 |
4 | class StandardPagination(PageNumberPagination):
5 | page_size = 10
6 | page_size_query_param = 'page_size'
7 | max_page_size = 50
8 |
--------------------------------------------------------------------------------
/Chapter15/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 |
--------------------------------------------------------------------------------
/Chapter15/educa/courses/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CoursesConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'courses'
7 |
--------------------------------------------------------------------------------
/Chapter15/educa/courses/forms.py:
--------------------------------------------------------------------------------
1 | from django.forms.models import inlineformset_factory
2 |
3 | from .models import Course, Module
4 |
5 | ModuleFormSet = inlineformset_factory(
6 | Course,
7 | Module,
8 | fields=['title', 'description'],
9 | extra=2,
10 | can_delete=True,
11 | )
12 |
--------------------------------------------------------------------------------
/Chapter15/educa/courses/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter15/educa/courses/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter15/educa/courses/templates/courses/content/file.html:
--------------------------------------------------------------------------------
1 |
2 | Download file
3 |
4 |
--------------------------------------------------------------------------------
/Chapter15/educa/courses/templates/courses/content/image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Chapter15/educa/courses/templates/courses/content/text.html:
--------------------------------------------------------------------------------
1 | {{ item.content|linebreaks }}
2 |
--------------------------------------------------------------------------------
/Chapter15/educa/courses/templates/courses/content/video.html:
--------------------------------------------------------------------------------
1 | {% load embed_video_tags %}
2 | {% video item.url "small" %}
3 |
--------------------------------------------------------------------------------
/Chapter15/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 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/Chapter15/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 |
9 | You have been successfully logged out.
10 | You can log-in again.
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter15/educa/courses/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter15/educa/courses/templatetags/__init__.py
--------------------------------------------------------------------------------
/Chapter15/educa/courses/templatetags/course.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 | register = template.Library()
4 |
5 |
6 | @register.filter
7 | def model_name(obj):
8 | try:
9 | return obj._meta.model_name
10 | except AttributeError:
11 | return None
12 |
--------------------------------------------------------------------------------
/Chapter15/educa/courses/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter15/educa/educa/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter15/educa/educa/__init__.py
--------------------------------------------------------------------------------
/Chapter15/educa/educa/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for educa project.
3 |
4 | It exposes the ASGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.asgi import get_asgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_asgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter15/educa/educa/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for educa project.
3 |
4 | It exposes the WSGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter15/educa/students/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter15/educa/students/__init__.py
--------------------------------------------------------------------------------
/Chapter15/educa/students/admin.py:
--------------------------------------------------------------------------------
1 | # Register your models here.
2 |
--------------------------------------------------------------------------------
/Chapter15/educa/students/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class StudentsConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'students'
7 |
--------------------------------------------------------------------------------
/Chapter15/educa/students/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from courses.models import Course
4 |
5 |
6 | class CourseEnrollForm(forms.Form):
7 | course = forms.ModelChoiceField(
8 | queryset=Course.objects.none(),
9 | widget=forms.HiddenInput
10 | )
11 |
12 | def __init__(self, *args, **kwargs):
13 | super(CourseEnrollForm, self).__init__(*args, **kwargs)
14 | self.fields['course'].queryset = Course.objects.all()
15 |
--------------------------------------------------------------------------------
/Chapter15/educa/students/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter15/educa/students/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter15/educa/students/models.py:
--------------------------------------------------------------------------------
1 | # Create your models here.
2 |
--------------------------------------------------------------------------------
/Chapter15/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 |
18 |
19 | {% endblock %}
20 |
--------------------------------------------------------------------------------
/Chapter15/educa/students/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter15/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | Pillow==10.3.0
4 | sqlparse==0.5.0
5 | django-braces==1.15.0
6 | django-embed-video==1.4.9
7 | pymemcache==4.0.0
8 | django-debug-toolbar==4.3.0
9 | redis==5.0.4
10 | django-redisboard==8.4.0
11 | djangorestframework==3.15.1
12 | requests==2.31.0
13 |
--------------------------------------------------------------------------------
/Chapter16/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.3-slim
2 |
3 | RUN apt-get update -qq \
4 | && rm -rf /var/lib/apt/lists/*
5 |
6 | # Set environment variables
7 | ENV PIP_DISABLE_PIP_VERSION_CHECK 1
8 | ENV PYTHONDONTWRITEBYTECODE 1
9 | ENV PYTHONUNBUFFERED 1
10 |
11 | WORKDIR /code
12 |
13 | COPY requirements.txt .
14 | RUN python -m pip install -r requirements.txt
15 | RUN python -m pip install psycopg[binary]
16 |
17 | COPY . .
--------------------------------------------------------------------------------
/Chapter16/educa/chat/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter16/educa/chat/__init__.py
--------------------------------------------------------------------------------
/Chapter16/educa/chat/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from chat.models import Message
4 |
5 |
6 | @admin.register(Message)
7 | class MessageAdmin(admin.ModelAdmin):
8 | list_display = ['sent_on', 'user', 'course', 'content']
9 | list_filter = ['sent_on', 'course']
10 | search_fields = ['content']
11 | raw_id_fields = ['user', 'course']
12 |
--------------------------------------------------------------------------------
/Chapter16/educa/chat/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ChatConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'chat'
7 |
--------------------------------------------------------------------------------
/Chapter16/educa/chat/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter16/educa/chat/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter16/educa/chat/routing.py:
--------------------------------------------------------------------------------
1 | from django.urls import re_path
2 |
3 | from . import consumers
4 |
5 |
6 | websocket_urlpatterns = [
7 | re_path(
8 | r'ws/chat/room/(?P\d+)/$',
9 | consumers.ChatConsumer.as_asgi(),
10 | ),
11 | ]
12 |
--------------------------------------------------------------------------------
/Chapter16/educa/chat/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter16/educa/chat/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 |
6 | app_name = 'chat'
7 |
8 | urlpatterns = [
9 | path(
10 | 'room//',
11 | views.course_chat_room,
12 | name='course_chat_room',
13 | ),
14 | ]
15 |
--------------------------------------------------------------------------------
/Chapter16/educa/courses/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter16/educa/courses/__init__.py
--------------------------------------------------------------------------------
/Chapter16/educa/courses/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter16/educa/courses/api/__init__.py
--------------------------------------------------------------------------------
/Chapter16/educa/courses/api/pagination.py:
--------------------------------------------------------------------------------
1 | from rest_framework.pagination import PageNumberPagination
2 |
3 |
4 | class StandardPagination(PageNumberPagination):
5 | page_size = 10
6 | page_size_query_param = 'page_size'
7 | max_page_size = 50
8 |
--------------------------------------------------------------------------------
/Chapter16/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 |
--------------------------------------------------------------------------------
/Chapter16/educa/courses/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CoursesConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'courses'
7 |
--------------------------------------------------------------------------------
/Chapter16/educa/courses/forms.py:
--------------------------------------------------------------------------------
1 | from django.forms.models import inlineformset_factory
2 |
3 | from .models import Course, Module
4 |
5 | ModuleFormSet = inlineformset_factory(
6 | Course,
7 | Module,
8 | fields=['title', 'description'],
9 | extra=2,
10 | can_delete=True,
11 | )
12 |
--------------------------------------------------------------------------------
/Chapter16/educa/courses/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter16/educa/courses/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter16/educa/courses/templates/courses/content/file.html:
--------------------------------------------------------------------------------
1 |
2 | Download file
3 |
4 |
--------------------------------------------------------------------------------
/Chapter16/educa/courses/templates/courses/content/image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Chapter16/educa/courses/templates/courses/content/text.html:
--------------------------------------------------------------------------------
1 | {{ item.content|linebreaks }}
2 |
--------------------------------------------------------------------------------
/Chapter16/educa/courses/templates/courses/content/video.html:
--------------------------------------------------------------------------------
1 | {% load embed_video_tags %}
2 | {% video item.url "small" %}
3 |
--------------------------------------------------------------------------------
/Chapter16/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 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/Chapter16/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 |
9 | You have been successfully logged out.
10 | You can log-in again.
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter16/educa/courses/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter16/educa/courses/templatetags/__init__.py
--------------------------------------------------------------------------------
/Chapter16/educa/courses/templatetags/course.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 | register = template.Library()
4 |
5 |
6 | @register.filter
7 | def model_name(obj):
8 | try:
9 | return obj._meta.model_name
10 | except AttributeError:
11 | return None
12 |
--------------------------------------------------------------------------------
/Chapter16/educa/courses/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter16/educa/educa/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter16/educa/educa/__init__.py
--------------------------------------------------------------------------------
/Chapter16/educa/educa/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for educa project.
3 |
4 | It exposes the WSGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter16/educa/students/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter16/educa/students/__init__.py
--------------------------------------------------------------------------------
/Chapter16/educa/students/admin.py:
--------------------------------------------------------------------------------
1 | # Register your models here.
2 |
--------------------------------------------------------------------------------
/Chapter16/educa/students/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class StudentsConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'students'
7 |
--------------------------------------------------------------------------------
/Chapter16/educa/students/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from courses.models import Course
4 |
5 |
6 | class CourseEnrollForm(forms.Form):
7 | course = forms.ModelChoiceField(
8 | queryset=Course.objects.none(),
9 | widget=forms.HiddenInput
10 | )
11 |
12 | def __init__(self, *args, **kwargs):
13 | super(CourseEnrollForm, self).__init__(*args, **kwargs)
14 | self.fields['course'].queryset = Course.objects.all()
15 |
--------------------------------------------------------------------------------
/Chapter16/educa/students/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter16/educa/students/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter16/educa/students/models.py:
--------------------------------------------------------------------------------
1 | # Create your models here.
2 |
--------------------------------------------------------------------------------
/Chapter16/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 |
18 |
19 | {% endblock %}
20 |
--------------------------------------------------------------------------------
/Chapter16/educa/students/tests.py:
--------------------------------------------------------------------------------
1 | # Create your tests here.
2 |
--------------------------------------------------------------------------------
/Chapter16/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.7.2
2 | Django~=5.0.4
3 | sqlparse==0.5.0
4 | Pillow==10.3.0
5 | django-braces==1.15.0
6 | django-embed-video==1.4.9
7 | pymemcache==4.0.0
8 | django-debug-toolbar==4.3.0
9 | redis==5.0.4
10 | django-redisboard==8.4.0
11 | djangorestframework==3.15.1
12 | requests==2.31.0
13 | channels[daphne]==4.1.0
14 | channels-redis==4.2.0
15 |
--------------------------------------------------------------------------------
/Chapter17/Dockerfile:
--------------------------------------------------------------------------------
1 | # Pull official base Python Docker image
2 | FROM python:3.12.3
3 |
4 | # Set environment variables
5 | ENV PYTHONDONTWRITEBYTECODE=1
6 | ENV PYTHONUNBUFFERED=1
7 |
8 | # Set work directory
9 | WORKDIR /code
10 |
11 | # Install dependencies
12 | RUN pip install --upgrade pip
13 | COPY requirements.txt .
14 | RUN pip install -r requirements.txt
15 |
16 | # Copy the Django project
17 | COPY . .
18 |
--------------------------------------------------------------------------------
/Chapter17/config/uwsgi/uwsgi.ini:
--------------------------------------------------------------------------------
1 | [uwsgi]
2 | socket=/code/educa/uwsgi_app.sock
3 | chdir = /code/educa/
4 | module=educa.wsgi:application
5 | master=true
6 | chmod-socket=666
7 | uid=www-data
8 | gid=www-data
9 | vacuum=true
10 |
--------------------------------------------------------------------------------
/Chapter17/educa/chat/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/chat/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/chat/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from chat.models import Message
4 |
5 |
6 | @admin.register(Message)
7 | class MessageAdmin(admin.ModelAdmin):
8 | list_display = ['sent_on', 'user', 'course', 'content']
9 | list_filter = ['sent_on', 'course']
10 | search_fields = ['content']
11 | raw_id_fields = ['user', 'course']
12 |
--------------------------------------------------------------------------------
/Chapter17/educa/chat/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ChatConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'chat'
7 |
--------------------------------------------------------------------------------
/Chapter17/educa/chat/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/chat/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/chat/routing.py:
--------------------------------------------------------------------------------
1 | from django.urls import re_path
2 |
3 | from . import consumers
4 |
5 |
6 | websocket_urlpatterns = [
7 | re_path(
8 | r'ws/chat/room/(?P\d+)/$',
9 | consumers.ChatConsumer.as_asgi(),
10 | ),
11 | ]
12 |
--------------------------------------------------------------------------------
/Chapter17/educa/chat/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter17/educa/chat/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 |
6 | app_name = 'chat'
7 |
8 | urlpatterns = [
9 | path(
10 | 'room//',
11 | views.course_chat_room,
12 | name='course_chat_room',
13 | ),
14 | ]
15 |
--------------------------------------------------------------------------------
/Chapter17/educa/courses/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/courses/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/courses/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/courses/api/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/courses/api/pagination.py:
--------------------------------------------------------------------------------
1 | from rest_framework.pagination import PageNumberPagination
2 |
3 |
4 | class StandardPagination(PageNumberPagination):
5 | page_size = 10
6 | page_size_query_param = 'page_size'
7 | max_page_size = 50
8 |
--------------------------------------------------------------------------------
/Chapter17/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 |
--------------------------------------------------------------------------------
/Chapter17/educa/courses/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CoursesConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'courses'
7 |
--------------------------------------------------------------------------------
/Chapter17/educa/courses/forms.py:
--------------------------------------------------------------------------------
1 | from django.forms.models import inlineformset_factory
2 |
3 | from .models import Course, Module
4 |
5 | ModuleFormSet = inlineformset_factory(
6 | Course,
7 | Module,
8 | fields=['title', 'description'],
9 | extra=2,
10 | can_delete=True,
11 | )
12 |
--------------------------------------------------------------------------------
/Chapter17/educa/courses/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/courses/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/courses/templates/courses/content/file.html:
--------------------------------------------------------------------------------
1 |
2 | Download file
3 |
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/courses/templates/courses/content/image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/courses/templates/courses/content/text.html:
--------------------------------------------------------------------------------
1 | {{ item.content|linebreaks }}
2 |
--------------------------------------------------------------------------------
/Chapter17/educa/courses/templates/courses/content/video.html:
--------------------------------------------------------------------------------
1 | {% load embed_video_tags %}
2 | {% video item.url "small" %}
3 |
--------------------------------------------------------------------------------
/Chapter17/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 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/Chapter17/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 |
9 | You have been successfully logged out.
10 | You can log-in again.
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/Chapter17/educa/courses/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/courses/templatetags/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/courses/templatetags/course.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 | register = template.Library()
4 |
5 |
6 | @register.filter
7 | def model_name(obj):
8 | try:
9 | return obj._meta.model_name
10 | except AttributeError:
11 | return None
12 |
--------------------------------------------------------------------------------
/Chapter17/educa/courses/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter17/educa/educa/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/educa/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/educa/settings/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/educa/settings/__init__.py
--------------------------------------------------------------------------------
/Chapter17/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': BASE_DIR / 'db.sqlite3',
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Chapter17/educa/educa/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for educa project.
3 |
4 | It exposes the WSGI callable as a module-level variable named
5 | ``application``.
6 |
7 | For more information on this file, see
8 | https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
9 | """
10 |
11 | import os
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'educa.settings')
16 |
17 | application = get_wsgi_application()
18 |
--------------------------------------------------------------------------------
/Chapter17/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 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/fonts/Roboto-Bold-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/admin/fonts/Roboto-Bold-webfont.woff
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/fonts/Roboto-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/admin/fonts/Roboto-Light-webfont.woff
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/fonts/Roboto-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/admin/fonts/Roboto-Regular-webfont.woff
--------------------------------------------------------------------------------
/Chapter17/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 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/img/icon-addlink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/img/icon-changelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/img/icon-deletelink.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/img/icon-yes.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/img/search.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/img/tooltag-add.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/img/tooltag-arrowright.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/admin/js/jquery.init.js:
--------------------------------------------------------------------------------
1 | /*global jQuery:false*/
2 | 'use strict';
3 | /* Puts the included jQuery into our own namespace using noConflict and passing
4 | * it 'true'. This ensures that the included jQuery doesn't pollute the global
5 | * namespace (i.e. this preserves pre-existing values for both window.$ and
6 | * window.jQuery).
7 | */
8 | window.django = {jQuery: jQuery.noConflict(true)};
9 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/debug_toolbar/css/print.css:
--------------------------------------------------------------------------------
1 | #djDebug {
2 | display: none !important;
3 | }
4 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/debug_toolbar/js/redirect.js:
--------------------------------------------------------------------------------
1 | document.getElementById("redirect_to").focus();
2 |
--------------------------------------------------------------------------------
/Chapter17/educa/static/redisboard/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/redisboard/favicon.ico
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/docs/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/docs/img/favicon.ico
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/docs/img/grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/docs/img/grid.png
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/Chapter17/educa/static/rest_framework/img/grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/static/rest_framework/img/grid.png
--------------------------------------------------------------------------------
/Chapter17/educa/students/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/students/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/students/admin.py:
--------------------------------------------------------------------------------
1 |
2 | # Register your models here.
3 |
--------------------------------------------------------------------------------
/Chapter17/educa/students/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class StudentsConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'students'
7 |
--------------------------------------------------------------------------------
/Chapter17/educa/students/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from courses.models import Course
4 |
5 |
6 | class CourseEnrollForm(forms.Form):
7 | course = forms.ModelChoiceField(
8 | queryset=Course.objects.none(),
9 | widget=forms.HiddenInput
10 | )
11 |
12 | def __init__(self, *args, **kwargs):
13 | super(CourseEnrollForm, self).__init__(*args, **kwargs)
14 | self.fields['course'].queryset = Course.objects.all()
15 |
--------------------------------------------------------------------------------
/Chapter17/educa/students/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/students/management/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/students/management/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/students/management/commands/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/students/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Django-5-By-Example/a4c1e4e917c7f68472bf575ef7bf3cf096e7e8e1/Chapter17/educa/students/migrations/__init__.py
--------------------------------------------------------------------------------
/Chapter17/educa/students/models.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your models here.
3 |
--------------------------------------------------------------------------------
/Chapter17/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 |
18 |
19 | {% endblock %}
20 |
--------------------------------------------------------------------------------
/Chapter17/educa/students/tests.py:
--------------------------------------------------------------------------------
1 |
2 | # Create your tests here.
3 |
--------------------------------------------------------------------------------
/Chapter17/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.8.1
2 | Django~=5.0.4
3 | Pillow==10.3.0
4 | sqlparse==0.5.0
5 | django-braces==1.15.0
6 | django-embed-video==1.4.9
7 | pymemcache==4.0.0
8 | django-debug-toolbar==4.3.0
9 | redis==5.0.4
10 | django-redisboard==8.4.0
11 | djangorestframework==3.15.1
12 | requests==2.31.0
13 | channels[daphne]==4.1.0
14 | channels-redis==4.2.0
15 | psycopg==3.1.18
16 | uwsgi==2.0.25.1
17 | python-decouple==3.8
18 |
--------------------------------------------------------------------------------