STAY INFORMED
following content serves as a personal note and may lack complete accuracy or certainty.

Minimal-Mistakes instruction
Useful vscode Shortcut Keys
Unix Commands
npm Commands
Vim Commands
Git Note
Useful Figma Shortcut Keys

2 minute read

Form

# forms.py

from django import forms

class PostForm(forms.Form):
    title = forms.CharField(max_length=50, label="title")
    content = forms.CharField(label="content", widget=forms.Textarea)

or you can refer to the model that you made before

from .models import Menu

class PostForm(forms.ModelForm):

    class Meta:
        model = Menu
        fields = '__all__' # ['name', 'description', 'price', 'img']

More info of Form Field

# views.py

from django.shortcuts import render, redirect
from .forms import PostForm

def post_create(request):
    if request.method == 'POST':
        post_form = PostForm(request.POST)

        if post_form.is_valid():
            new_post = post_form.save()
            return redirect('post-detail', post_id = new_post.id)

    else:
        post_form = PostForm()

    return render(request, 'posts/post_form.html', {'form': post_form})
<!-- post_form.html -->
<form>
  {% csrf_token %} {{form.as_ul}}
  <input type="submit" , value="Submit" />
</form>

csrf_token: security system offered by django

Validation

You can simply use internal validators. This is to check whether title is duplicated or not.

#models.py

class Post(models.Model):
    title = models.CharField(max_length=50, error_message={'unique': 'Cannot be duplicated'})

or you can import external validators.

#models.py

from django.core.validators import MinLengthValidator

class Post(models.Model):
    content =  models.TextField(validators=[MinLengthValidator(10, 'minimum length is 10')])

More info of validators

Also you can create validation function.

#validators.py

from django.core.exceptions import ValidationError

def validate_symbols(value):
    if("@" in value) or ("#" in value):
        raise ValidationError('"@" or "#" cannot be included', code = 'symbol-err')
# models.py

from .validators import validate_symbols

class Post(models.Model):
    content =  models.TextField(validators=[MinLengthValidator(10, 'minimum length is 10'), validate_symbols])

You can also create a validate function in PostForm class and handle it.

# forms.py

from django import forms
from .models import Post
from .validators import validate_symbols
from django.core.exceptions import ValidationError

class PostForm(forms.ModelForm):


    class Meta:
        model = Post
        fields = '__all__'

    def clean_title(self):
        title = self.cleaned_data['title']
        if '*' in title:
            raise ValidationError('* cannot be included')

        return title

Form HTML

{% extends './base.html' %}
{% load static %}

{% block css%}
    <link rel="stylesheet" href="{% static 'posts/css/form.css' %}" >
{% endblock css%}

{% block content %}
<form method="post">{% csrf_token %}
    <h3>Title</h3>
    <p class="error">{{form.title}}</p>
    {% for error in form.title.errors %}
    <p class="error">{{error}}</p>
    {% endfor %}
    <h3>Content</h3>
    <p class="error">{{form.content}}</p>
    {% for error in form.content.errors %}
    <p class="error">{{error}}</p>
    {% endfor %}
    <input type="submit", value="Submit">
</form>
{% endblock content %}

Post Update

def post_update(request, post_id):
    post = Post.objects.get(id=post_id)

    if request.method == 'POST':
        post_form = PostForm(request.POST, instance=post)
        if post_form.is_valid():
            post_form.save()
            return redirect('post-detail', post_id = post.id)
        
    else:
        post_form = PostForm(instance=post)

    return render(request, 'posts/post_form.html', {'form': post_form})

Post Delete

def post_delete(request, post_id):
    post = Post.objects.get(id=post_id)
    post.delete()
    return redirect('post-list')
Learned New

You can make view function to class

# function

def post_create(request):
    if request.method == 'POST':
        post_form = PostForm(request.POST)

        if post_form.is_valid():
            new_post = post_form.save()
            return redirect('post-detail', post_id = new_post.id)

    else:
        post_form = PostForm()

    return render(request, 'posts/post_form.html', {'form': post_form})

# url
path('posts/new', views.post_create, name='post-create')
# class

from django.views.generic import CreateView

class PostCreateView(CreateView):
    model = Post
    form_class = PostForm
    template_name = 'posts/post_form.html'

    def get_success_url(self):
        return reverse('post-detail', kwargs={'post_id': self.object.id})


# url
path('posts/new', views.PostCreateView.as_view(), name='post-create')

Tags:

Categories:

Updated: