36.    My Django Study

August, 2020
home

Contents

01. to start

02. create a simple django website from scratch

------ initial setup ------

------ add project ------

------ add the first app without model ------


            # intros/views.py
            from django.views.generic import TemplateView

            class HomePageView(TemplateView):
                template_name = 'home.html'
            
            # django.views.generic is a module.
            # TemplateView is a class.
            # HomePageView inherits from TemplateView, for most of the works.
                       
            # pk_project/urls.py   adding
            from django.urls import path, include
                ....
                path('', include('intros.urls')),

            # intros/urls.py
            from django.urls import path

            from .views import HomePageView
            urlpatterns = [
                path('', HomePageView.as_view(), name='home'),
            ]   

            
            # .views means that at current folder, views is the file name.
            # In the file, module, import class HompageView.
            # The 3rd parameter in path is the url name used in django url tag in a html file.
            # In the 2nd parameter, function as_view() makes the class acts like a callable function,
            #         make it as  a HTTP event handler for request and response.
            
            

------ more 1: start to use admin ------

------ more 2: many html pages with a common menu on the top ------

-------------- templates/base.html ----------------
<header >
   <a href="{% url 'home' %}" > Home </a > |
   <a href="{% url 'contact' %}"> Contact </a >
</header >
{% block content %}
{% endblock content %}

------------ templates/home.html --------------------
{% extends 'base.html' %}
{% block content %}
    Home Page
{% endblock content %}

------- templates/contact.html ---------------------
the same way

-------- intros/views.py--------------------------
class ContactPageView(TemplateView):
     template_name = 'contact.html'

---------intros/urls.py ---------------------------
from .views import HomePageView, ContactPageView
...
      path('contact/', ContactPageView.as_view(), name='contact'),



03. copy a django website with Modal class

------ create a website, not from sample code. ------


----- Model, buidt-in model-user,primary key, foreign key ------------


    # blog/models.py
    class Post(models.Model):
        title = models.CharField(max_length=200)
        author = models.ForeignKey(
                    'auth.User',
                    on_delete=models.CASCADE,
                )

        body = models.TextField()
                

------ peek two tables in db Browser for sqlite

------ admin, test the website --------------



----- list page, detail page,   from list to detail    ------------


# File blog/views.py includes classBlogListView and BlogDetailView 

# blog/urls.py
    path('post/<int:pk>/', BlogDetailView.as_view(), name='post_detail'),
    path('', BlogListView.as_view(), name='home'),

# templates/home.html
{% extends 'base.html' %}

{% block content %}
  {% for post in object_list %}
  <div class="post-entry">
    <h2><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a></h2>
    <p>{{ post.body }}</p>
  </div>
  {% endfor %}
{% endblock content %}    
                

04. Review the django website with Modal class

05. data reference

                ---  blog/models.py ------
                class Comment(models.Model):
                    post = models.ForeignKey(
                        Post,
                        on_delete=models.CASCADE,
                    )
                    comment = models.CharField(max_length=140)
                    author = models.ForeignKey(
                        'auth.User',
                        on_delete=models.CASCADE,
                    )

                --- blog/admin.py --------
                from .models import Post, Comment

                admin.site.register(Comment) 
            
                ---  blog/admin.py ------
                class CommentInline(admin.TabularInline): 
                    model = Comment
                    extra = 0

                class PostAdmin(admin.ModelAdmin): 
                    inlines = [
                    CommentInline,
                ]

                admin.site.register(Post, PostAdmin) 
            
    ------   blog/models.py  ------
    class Comment(models.Model):
        post = models.ForeignKey(
            Post,
            on_delete=models.CASCADE,
            related_name='comments',
        )
            
            
----- templates/home.html, adding the inner loop ----- {% for post in object_list %} --- post contents ---- {% for comment in post.comments.all %} {{comment.author}} · {{comment}} {% endfor %} {% endfor %}
    -----  templates/post_detail.html,   add the same inner loop   -----
    {% block content %}
        {{ post.title }}
        {{ post.body }}

        {% for comment in post.comments.all %}
            {{comment.author}} · {{comment.comment}}
        {% endfor %} 
    {% endblock content %}
    
    ---- the variable from the server is post.
            

06.one comment

07. create a simple rest web service

--- step 1, inital setup ---

                ---- settings.py 
                'blog.apps.BlogConfig',
                
                ----  blog/models.py   
                from django.db import models

                class Post(models.Model):
                    title = ...
                    author = models.ForeignKey(
                        'auth.User',
                        on_delete=models.CASCADE,
                    )
                    body = ...
                ...
                
---- blog/admin from .models import Post admin.site.register(Post)

--- step 2, applying Django REST framework ---

                ---- settings.py 
                'rest_framework',
                
---- blog_project/urls.py path('restws/', include('blog.urls'))
---- blog/urls.py path('<int:pk>/', BlogDetailView.as_view()), path('', BlogListView.as_view(), name='home'),
                ---- blog/views.py   
                from rest_framework import generics

                from .models import Post
                from .serializers import PostSerializer

                class BlogListView(generics.ListAPIView):
                    queryset = Post.objects.all()
                    serializer_class = PostSerializer

                class BlogDetailView(generics.RetrieveAPIView):
                    queryset = Post.objects.all()
                    serializer_class = PostSerializer
            


                --- 
                from rest_framework import serializers

                from .models import Post

                class PostSerializer(serializers.ModelSerializer):
                    class Meta:
                        model = Post
                        fields = ('title', 'author', 'body')
            

--- step 3, test and comments ---

08. CRUD

--- Review Blowsable API----

--- CRUD for REST web service ---

09. CRUD for web pages

--- step 1, find a app root folder to begin ----

--- step 2, views ----

                class BlogCreateView(CreateView):
                    model = Post
                    template_name = 'post_new.html'
                    fields = ['title', 'author', 'body']
                class BlogUpdateView(UpdateView):
                    model = Post
                    template_name = 'post_edit.html'
                    fields = ['title', 'body']
                class BlogDeleteView(DeleteView): 
                    model = Post
                    template_name = 'post_delete.html'
                    success_url = reverse_lazy('home')
            

--- step 3, Create a post ----

3.1, adding a path in urls.py
        #blog/urls.py        add the following line
        path('post/new/', BlogCreateView.as_view(), name='post_new'),
            
3.2, a user starts to create a post
3.3, post_new.html
        # after click new page link, navigate to the page
        <form action="" method="post">{% csrf_token %}
            {{ form.as_p }}
            < input type="submit" value="Save" />
        </form >
            
3.4, redirect to the detail page when done
        # defined in a function blog/models.py
    from django.urls              import reverse
    ...
    class Post(models.Model):
        def get_absolute_url(self):
            return reverse('post_detail', args=[str(self.id)])
            
3.5, review the new sequence
  1. The user accesses the home page. click the new blog link.
  2. The BlogCreateView provides a page with the form for a new blog.
  3. The user fills the new form, and click save.
  4. The BlogCreateView responds again, processing the new blog,
  5.    and redirect the detail page to the user.
3.6, create lab

--- step 4, Update a post ----

    overview the update sequence
  1. The user accesses the detail page. click link update.
  2. The view provides a page with the form for update.
  3. The user fills the update form, and click the link for edit.
  4. The view processes the update.
  5. The view redirect the detail page to the user.
        todolist  
        # blog/urls.py          
               path('post/<int:pk>/edit/', BlogUpdateView.as_view(), name='post_edit'),
        # templates/post_detail.html
               <a href="{% url 'post_edit' post.pk %}">+ Edit Blog Post</a>
        # create templates/post_edit.html
               add a similar code for update
            

--- step 5, delete a post ----

    overview the delete sequence
  1. The user accesses the detail page. click link delete.
  2. The view provides a page with the form for delete.
  3. The user click the link confirm for delete.
  4. The view processes the delete.
  5. The view redirect the home page to the user.
        todolist  
        # blog/urls.py          
                path('post/<int:pk>/delete/', BlogDeleteView.as_view(), name='post_delete'),
                    
        # create templates/post_delete.html
        # in the form 
                <a href="">delete</a>
                add a button to confirm

        # redirect after completing a delete
        # It is defined in its view
        #  blog/views.py    
            class BlogDeleteView(DeleteView): 
                    model = Post
                    template_name = 'post_delete.html'
                    success_url = reverse_lazy('home')     
        
        #The function is called first, its object address is converted to its url address,and wait.
        #When the completion is sensed, the function will be executed.