[PYTHON] [Django] Added new question creation function to polls app

I want to add functionality after creating a voting app with Django's official documentation

After learning how the framework works by following Django's official documentation, I'd like to add some features and implement it. I made it.

Introduction

-In Django's official documentation, you can touch and learn Django while creating a simple voting app from scratch.

・ I first touched Django in the official Django documentation, but I felt that the explanation was not polite for beginners, so I stopped learning in this tutorial while creating the app, and [Udemy's Django teaching materials](https: / I decided to learn the basics of the basics at /www.udemy.com/course/django-3app/) (the best-selling Django search).

・ After learning the basics of Django with Udemy's teaching materials, I went back to the official document and completed the creation of the voting app.

environment

-Python 3.8.2 ・ Django 3.0.3 ・ OS is both Windows 10 and macOS

Create additional functions (create new questions & choices)

Voting apps created in the official documentation must use the admin user screen to add questions and choices. I would like to add a new creation screen on the general user screen as well.

Implementation method

-Implement using CreateView ・ Create a link to the question creation page on the question list page -First create a new question in the Question table ・ After that, create a new option linked to the question

Complete image

image.png

code

[views.py]

polls/views.py


#import omitted

#abridgement

class QuestionCreate(CreateView):
    #template_name = 'polls/createquestion.html'
    model = Question
    fields = ('question_text',)
    success_url = reverse_lazy('polls:index')


class ChoiceCreate(CreateView):
    model = Choice
    fields = ('choice_text',)
    success_url = reverse_lazy('polls:index')

    def dispatch(self, request, *args, **kwargs):
        self.question = get_object_or_404(Question, pk=kwargs['question_id'])
        return super().dispatch(request, *args, **kwargs)

    def form_valid(self, form):
        form.instance.question = self.question
        return super().form_valid(form)

(1) The reason why the template name is not described as "template_name = (arbitrary screen name) .html" (commented out) is If the screen name is "model name \ _form.html", CreateView and the screen will be automatically linked.

(2) If there is only one column to specify in fields, a comma (,) is required after the column name.

③ The most troublesome thing is Choice Create What is dispatch doing? Overriding the existing View class method dispatch.

Since choice must be associated with question, question_id is specified in dispatch.

Basically, it is considered that there are many cases where the form such as def XXXX (): is overridden in the general-purpose view (CreateView etc.). (I admit the objection ...)

If you are interested, please refer to the definition of general view.

[urls.py]

polls/urls.py


#import omitted

app_name = 'polls'
urlpatterns = [

    #Omitted because it is the same as the official document

    path('question_create/', views.QuestionCreate.as_view(),
        name='questioncreate'),

    path('<int:question_id>/choice_create/', views.ChoiceCreate.as_view(),
        name='choicecreate'),
]

[models.py]

polls/models.py



class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published', auto_now_add=True)

    def __str__(self):
        return self.question_text

Add ʻauto_now_add = True` to the second argument of pub_date.

[templates]

polls/templates/polls/index.html


{% if latest_question_list %}
<ul>
    {% for question in latest_question_list %}
    <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a>
    {% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}

<a href="{% url 'polls:questioncreate' %}">New Question</a>

Add a link to the new question creation screen on the last line.

polls/templates/polls/question_form.html



<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save">
</form>

polls/templates/polls/choice_form.html



<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save">
</form>

Finally

Thank you for watching until the end! Since this article was my first post on Qiita, I think there were a lot of things that didn't work, but I hope it helps those who are having trouble adding similar functions. I took a long time to implement this. .. ..

Basically, the generic view corresponds to one model. Since this app has to add new content to the two tables, we have implemented question creation and choice creation separately.

I really wanted to create a question and associated options on one screen, but I couldn't implement it with my current technology. It may have been possible by joining the Question and Choice tables, but ...

This time I added a new creation function, but I am also considering adding an edit / delete function. If I can afford it, I will post it on Qiita.

If you have any suggestions or questions, please feel free to contact @ hiyoku0918!

Recommended Posts

[Django] Added new question creation function to polls app
Django Tutorial (Blog App Creation) ⑤ --Article Creation Function
Added achievement function to Sublime Text
Added a function to register desired shifts in the Django shift table
Django Tutorial (Blog App Creation) ④ --Unit Test
Django shift table shift data creation function completed
Django shift creation function Added basic work shift registration function for days of the week
Django Tutorial (Blog App Creation) ① --Preparation, Top Page Creation
I added a function to CPython (ternary operator)
How to develop a cart app with Django
Django Tutorial (Blog App Creation) ③ --Article List Display
Until you create a new app in Django
Django Tutorial (Blog App Creation) ⑦ --Front End Complete
I want to upload a Django app to heroku