Introduction
I'm not doing Django, Vue.js recently. So, need to write a simple blog post to refresh things. Will use Vue.js in script mode, like jQuery or other JS libs, without any build tools. And I'm not going to use any auth for keeping it simple
This blog post teaches neither Django nor Vue. Feel free to visit some resources below
https://docs.djangoproject.com/en/3.2/intro/tutorial01/
https://tutorial.djangogirls.org/en/
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website
https://vuejs.org/v2/guide/
https://www.vuemastery.com/courses/intro-to-vue-js/vue-instance/
Disclaimer
This article does NOT follow any best practices. It teaches neither Django nor Vue. I'm just touching some basics to refresh my knowledge. That's the purpose of the article.
Django side
Install and start project
pip install django
mkdir django-vue-project && cd django-vue-project/ && django-admin startproject config .
python manage.py startapp app1
Add app1
to INSTALLED_APPS
in settings.py
After your edits, it would be something like below
# config/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app1',
]
Follow https://github.com/adamchainz/django-cors-headers and configure cors.
Create Models
# app1/models.py
# Create your models here.
class Todo(models.Model):
todo = models.TextField()
is_done = models.BooleanField()
python manage.py makemigrations
python manage.py migrate
Enabling Django Admin, for Todo model
Create a superuser, so you can access admin pages. Note both username
and password
will be admin
python manage.py shell -c "from django.contrib.auth import get_user_model; User=get_user_model(); a=User.objects.create(username='admin'); a.set_password('admin'); a.is_superuser=True; a.is_staff=True; a.save()"
Edit admin.py to enable Todo manipulation in django admin pages
# app1/admin.py
# Register your models here.
admin.site.register(Todo)
Run django dev server
python manage.py runserver
Visit following URL to create few Todo items
http://localhost:8000/admin/app1/todo/
Create List Todos End point
Create a ListView
# app1/views.py
from django.views import View
from django.http import JsonResponse
from app1.models import Todo
# Create your views here.
class TodoListView(View):
def get(self, request):
todos = list(Todo.objects.values_list('id', 'todo','is_done',))
return JsonResponse(todos,safe=False)
CreateView
Change app1/views.py as follows.
# app1/views.py
# ...
from app1.models import Todo
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
# ...
@method_decorator(csrf_exempt, name='dispatch')
class TodoCreateView(View):
def post(self, request):
data = {
'todo' : request.POST.get('todo'),
'is_done': False
}
todo = Todo(**data)
todo.save()
return JsonResponse({'status':'saved','id':todo.id})
UpdateView
Again change app1/views.py
@method_decorator(csrf_exempt, name='dispatch')
class TodoUpdateView(View):
def put(self, request, pk):
todo = Todo.objects.get(pk=pk)
# Workaround
# https://dzone.com/articles/parsing-unsupported-requests-put-delete-etc-in-dja
request.method = "POST"
request._load_post_and_files()
request.PUT = request.POST
# End Workaround
todo.todo= request.PUT.get('todo')
todo.save()
return JsonResponse({'status':'saved','id':todo.id})
DeleteView
Change app1/views.py
@method_decorator(csrf_exempt, name="dispatch")
class TodoDeleteView(View):
def dispatch(self, request, *args, **kwargs):
# https://micropyramid.com/blog/introduction-to-django-class-based-views/
pk = kwargs.get("pk")
return self.delete(request, pk)
def delete(self, request, pk):
# Workaround
# https://dzone.com/articles/parsing-unsupported-requests-put-delete-etc-in-dja
request.method = "POST"
request._load_post_and_files()
request.DELETE = request.POST
# End Workaround
todo_qs = Todo.objects.filter(pk=pk)
is_todo_exists = todo_qs.exists()
if is_todo_exists:
todo = todo_qs.delete()
return JsonResponse(
{"status": "deleted"}
)
else:
return JsonResponse({"status": "failed", "message": "deletion failed"})
Vue Js Code
Just copy pasted the code here
var headers = { 'Content-Type': 'multipart/form-data' }
var app = new Vue({
el: '#app',
data: {
message: 'hello world',
todos: [
{
pk: 1,
todo: 'todo1',
is_done: false,
},
{
pk: 2,
todo: 'todo2',
is_done: false,
},
{
pk: 1,
todo: 'todo3',
is_done: false,
},
],
todo: null,
pk: null,
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
},
loadData: function () {
var that = this
axios.get('http://localhost:8000/').then(function (response) {
console.log(response)
that.todos = response.data
})
},
saveThisTodo: function () {
var that = this
var todoData = new FormData();
todoData.append('todo', this.todo)
axios.post('http://localhost:8000/api/todo/create/', todoData, headers).then(function (response) {
console.log(response)
console.log('Saved')
that.loadData()
})
},
updateTodo: function () {
var todoData = new FormData();
todoData.append('todo', this.todo)
var that = this
axios.put('http://localhost:8000/api/todo/update/' + this.pk, todoData, headers).then(function (response) {
console.log(response)
console.log('Updated')
that.loadData()
})
},
editTodo: function (item) {
console.log('Oh yeah: its time for edit')
this.todo = item.todo
this.pk = item.pk
},
deleteTodo: function (item) {
var that = this
axios.delete('http://localhost:8000/api/todo/delete/' + item.pk, headers).then(function (response) {
console.log(response)
console.log('Saved')
that.loadData()
})
}
},
mounted: function () {
this.loadData()
}
})
Conclusion
This blog post only shares the distant glimpses of what I have done. To get full idea, visit github repo here https://github.com/ajeebkp23/worst-crud-todo-app-vue-django
Top comments (0)