Post List API
API endpoint that enables a list of posts to be browsed including related models data and auxhiliary properties.
The configured endpoint purposefully does not permit a POST method as I do not want others creating new posts in the database.
GET /api/blog/posts/?format=api&offset=15
{ "count": 17, "next": null, "previous": "https://waynelambert.dev/api/blog/posts/?format=api&limit=3&offset=12", "results": [ { "id": 8, "title": "Protected Admin Page with Password Reset Feature", "slug": "protected-admin-page-password-reset-feature", "content": "In this quick tutorial, we are going to learn how to protect your application against malicious automated scripts that look for admin panels. Since in Django and WordPress applications, these are located at the standard /admin path of a website, it is advisable to change your admin location. This is actually really easy to do. This is just another security measure that should be taken prior to deployment.</p>\n\n<p>Firstly, in your <strong>.env</strong> file which should be located within your project's source directory (the same level as your <strong>manage.py</strong> file), set up an environment variable called <strong>ADMIN_ALIAS</strong> or something similar.</p>\n\n<pre>\n<code>ADMIN_ALIAS=custom-slug-to-admin-panel</code></pre>\n\n<p>You can, of course, change the example string <strong>custom-slug-to-admin-panel</strong> to be whatever your preferred location of the admin panel will be.</p>\n\n<p>Next up, when your project runs, it needs to get the environment variable into the settings. For a simple, key/value pair storage within your <strong>.env</strong> file, this is achieved like this.</p>\n\n<pre>\n<code class=\"language-python\"># In your project's settings.py\n\n# Additional field to adjust the login point for the Admin site\nADMIN_ALIAS = os.environ['ADMIN_ALIAS']</code></pre>\n\n<p>Finally, all of the URLs within your project that pertain to the admin panel need some adjustments so that when the administrator of the website navigates to them, they will still access them as they would do if the admin was delivered out of the box by Django.</p>\n\n<pre>\n<code class=\"language-python\">from django.contrib.auth import views as auth_views\nfrom django.urls import path\nfrom my_project.settings import ADMIN_ALIAS\n\n\nurlpatterns = [\n path(\n f'{ADMIN_ALIAS}/password_reset/',\n auth_views.PasswordResetView.as_view(),\n name='admin_password_reset',\n ),\n path(\n f'{ADMIN_ALIAS}/password_reset/done/',\n auth_views.PasswordResetDoneView.as_view(),\n name='password_reset_done',\n ),\n path(\n 'reset/<uidb64>/<token>/',\n auth_views.PasswordResetConfirmView.as_view(),\n name='password_reset_confirm',\n ),\n path(\n 'reset/done/',\n auth_views.PasswordResetCompleteView.as_view(),\n name='password_reset_complete',\n ),\n path(f'{ADMIN_ALIAS}/', admin.site.urls),\n ...\n]</code></pre>\n\n<p>Now, your site has an additional level of protection applied.</p>", "reference_url": "", "publish_date": "2019-07-29T15:55:32.192000Z", "updated_date": "2019-07-31T15:55:32.192111Z", "image": "https://wl-portfolio.s3.amazonaws.com/post_images/protected-admin-page.jpg", "status": "Publish", "word_count": 276, "reading_time": 4, "post_absolute_url": "/blog/post/protected-admin-page-password-reset-feature/", "author_username": "wayne-lambert", "author_first_name": "Wayne", "author_last_name": "Lambert", "author_full_name": "Wayne Lambert", "author_initials": "WL", "author_display_name": "Wayne Lambert", "author_join_year": 2019, "author_view": 1, "author_created_date": "2019-07-21T10:02:09.888000Z", "author_updated_date": "2022-12-14T14:44:36.068604Z", "author_absolute_url": "/blog/users/wayne-lambert/profile/", "author_profile_picture": "https://wl-portfolio.s3.amazonaws.com/profile_pics/gravatar-500.jpg", "categories": [ { "id": 1, "name": "Django", "slug": "django", "created_date": "2019-07-27T21:39:31.016414Z" } ] }, { "id": 7, "title": "Embedding CK Editor into Django Blog App", "slug": "embedding-ck-editor-django-blog-app", "content": "<p>The content fields for the blog posts on this site have been created using a rich text WYSIWYG editor called CK Editor.</p>\n\n<p>This is a JavaScript based editor that can be added to a Django project to give it the ability to add rich text and media to the website.</p>\n\n<p>To implement this, firstly you will need to install the CK Editor. My configuration uses pipenv as the package manager and the installation is being completed within the project's root directory (called <strong>src</strong> in my case).</p>\n\n<p>Navigate to your project's root directory and spin up a virtual environment using pipenv.</p>\n\n<pre>\n<code class=\"language-bash\">$ pipenv shell</code></pre>\n\n<p> Install Django CK Editor...</p>\n\n<pre>\n<code class=\"language-bash\">(src) $ pipenv install django-ckeditor</code></pre>\n\n<p> Then, you will need to register it within your settings area so that Django knows that it is available to your project.</p>\n\n<pre>\n<code class=\"language-python\"># In settings.py\n\nINSTALLED_APPS = [\n 'django.contrib.admin',\n 'django.contrib.auth',\n 'django.contrib.contenttypes',\n 'django.contrib.sessions',\n 'django.contrib.messages',\n 'django.contrib.staticfiles',\n\n # Third Party\n ...\n 'ckeditor', # Add\n 'ckeditor_uploader', # Add\n ...\n\n # Project Apps\n 'myapp.apps.MyappConfig',\n ...\n]</code></pre>\n\n<p>Towards the bottom of your project settings, you will need to insert the following code:</p>\n\n<pre>\n<code class=\"language-python\"># In settings.py\n...\n\nCKEDITOR_UPLOAD_PATH = 'uploads/'\n\nCKEDITOR_CONFIGS = {\n 'default': {\n 'toolbar': 'Custom',\n 'toolbar_Custom': [\n ['Styles', 'Format', 'Bold', 'Italic', 'Underline', 'Strike',\n 'SpellChecker', 'Undo', 'Redo'],\n ['Link', 'Unlink', 'Anchor'],\n ['Image', 'Table', 'HorizontalRule'],\n ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-',\n 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],\n ['TextColor', 'BGColor'],\n ['Smiley', 'SpecialChar'],\n ['RemoveFormat', 'CodeSnippet'],\n ],\n 'extraPlugins': 'codesnippet',\n }\n}\n\n...</code></pre>\n\n<p>You will need an HTML field within a suitable field within your model. In my case, and perhaps the most canonical example, is a post content field for a blog.</p>\n\n<p>One of the fields within your model will need to be declared as a rich text uploading field so that you can do things like upload images to the field.</p>\n\n<pre>\n<code class=\"language-python\"># In myapp.models.py\n\nfrom ckeditor_uploader.fields import RichTextUploadingField\n\n\nclass Post(models.Model):\n ...\n content = RichTextUploadingField()\n ...</code></pre>\n\n<p>You will need to place a reference to the CK Editors in-built urls.py file within your project's urls.py file.</p>\n\n<pre>\n<code class=\"language-python\"># In your project's urls.py\n\nurlpatterns = [\n ... ,\n path('ckeditor/', include('ckeditor_uploader.urls')),\n ... ,\n]</code></pre>\n\n<p>You will then be able to benefit from having rich text at your disposal when you're creating content fields in your application.</p>\n\n<p>If you would like to see the detail for where I learned how to implement this, please check out the video tutorial using the link below.</p>\n\n<p><a href=\"https://www.youtube.com/watch?v=L6y6cn1XUfw\">How to Implement CK Editor into your Django Site</a></p>", "reference_url": "", "publish_date": "2019-07-26T15:55:01.031000Z", "updated_date": "2019-07-31T15:55:01.031690Z", "image": "https://wl-portfolio.s3.amazonaws.com/post_images/html.jpg", "status": "Publish", "word_count": 409, "reading_time": 6, "post_absolute_url": "/blog/post/embedding-ck-editor-django-blog-app/", "author_username": "wayne-lambert", "author_first_name": "Wayne", "author_last_name": "Lambert", "author_full_name": "Wayne Lambert", "author_initials": "WL", "author_display_name": "Wayne Lambert", "author_join_year": 2019, "author_view": 1, "author_created_date": "2019-07-21T10:02:09.888000Z", "author_updated_date": "2022-12-14T14:44:36.068604Z", "author_absolute_url": "/blog/users/wayne-lambert/profile/", "author_profile_picture": "https://wl-portfolio.s3.amazonaws.com/profile_pics/gravatar-500.jpg", "categories": [ { "id": 1, "name": "Django", "slug": "django", "created_date": "2019-07-27T21:39:31.016414Z" } ] } ] }