3

Background Hello All, trying to build a 'retrospective app' using Django & VUE. I have already created login, and dashboard which displays list of 'boards' created by logged in user. A board is a table of topics anyone with link can add and log-in not required.

Problem When I click on board, it is showing all the topics in DB, How can I pass 'PK' of board from Vue CDN to Django DRF to get filtered results.

Env: Django, VUE.js, Django Rest Frame Work

Please note: Very new to Django & VUE this is my first project ever in my life, learning for the past 8months, please go easy on me.

Below is the Board.html, with Vue CDN.

{% load static %}
{% block content %}
<div id="app">
    <div class="container">
        <form @submit.prevent="submitForm">
            <div class="form-group row">
                <input type="text" class="form-control col-3 mx-2" placeholder="Todo" v-model="retroboard.todo">
                <input type="text" class="form-control col-3 mx-2" placeholder="inprogress"
                    v-model="retroboard.inprogress">
                <input type="text" class="form-control col-3 mx-2" placeholder="Action Items" v-model="retroboard.done">
                <button class="btn btn-success">Submit</button>
            </div>
        </form>
        <!-- <div>
            <form method="POST">
                {% csrf_token %}
                {{form.todo}}
                {{form.inprogress}}
                {{form.done}}
                <button class="btn btn-primary">Add</button>
            </form>
      
        </div> -->
        <table class="table">
            <thead>
                <th>Todo</th>
                <th>InProgress</th>
                <th>Done</th>
            </thead>
            <tbody>
                <tr v-for="board in retroboards" :key="board.id" @dblclick="$data.retroboard = board">
                    <td>[[ board.todo ]]
                        <a href=" "> <i class=" fa fa-heart"></i> </a>
                        <a href=" "> <i class="fa fa-trash"></i> </a>
                    </td>
                    <td>[[ board.inprogress ]]</td>
                    <td>[[ board.done ]]</td>
                    <td> <button class="btn btn-outline-danger btn-sm mx-1" @click="deleteTopic(board)">x</button>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
<!-- Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.js"></script>

<script>
    var app = new Vue({
        el: '#app',
        delimiters: ['[[', ']]'],
        data() {
            return {
                retroboard: {
                    "todo": '',
                    "inprogress": '',
                    "done": '',
                    "id": ''
                },
                retroboards: [],
            }
        },
        async created() {
            await this.getRetroTopics();
        },
        methods: {

            submitForm() {
                if (this.retroboard.id === undefined) {
                    this.createRetroTopic();
                } else {
                    this.editRetroTopic();
                }
            },
            async getRetroTopics() {
                var response = await fetch("http://127.0.0.1:8000/api/retroboard/");
                this.retroboards = await response.json();
            },
            async createRetroTopic() {
                await this.getRetroTopics()
                await fetch("http://127.0.0.1:8000/api/retroboard/", {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRFToken': csrftoken,
                    },
                    body: JSON.stringify(this.retroboard)
                });
                // this.retroboards.push(await response.json());
                await this.getRetroTopics();
                this.retroboard = {};
            },

            async editRetroTopic() {
                await this.getRetroTopics()
                await fetch(`http://127.0.0.1:8000/api/retroboard/${this.retroboard.id}/`
                    , {
                        method: 'PUT',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-CSRFToken': csrftoken,
                        },
                        body: JSON.stringify(this.retroboard)
                    });
                await this.getRetroTopics();
                this.retroboard = {};
            },

            async deleteTopic(retroboard) {
                await this.getRetroTopics()
                await fetch(`http://127.0.0.1:8000/api/retroboard/${retroboard.id}/`
                    , {
                        method: 'delete',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-CSRFToken': csrftoken,
                        },
                        body: JSON.stringify(this.retroboard)
                    });
                await this.getRetroTopics();
            }

        }

    })
</script>

{% endblock %}```

1 Answers1

1

A bit late but.

I suggest you to use slot with props. Most of time it's the best way to serve Django vars into vue.

For example :

index.js :

let myComponent = {
    data    : function() {
        return {
            in_message : "Hello World !",
        }
    },
    props   : {
        p_url   : String,
        p_pk    : Number,
    },
    methods     : {},
    template    : " \
        <div alt='Slot must be surround'> \
            <slot \
                :out_message='in_message' \
            ></slot> \
        </div> \
    ",
}

var app = new Vue({
    delimiters  : ['[[', ']]'],
    el          : '#app',
    components  : {
        myComponent
    },
})

index.html

<html>
    <head>
        <title>Django | VueJS {% trans " are working together "%}</title>
    </head>
    <body>
        {% with message="Django" url="/" pk=1 %}
            <my-component
                p_url='{{ url }}'
                p_pk='{{ pk}}'
            >
                <template v-slot:default='my_slot_name'>
                    <p>{{message}} | [[ my_slot_name.out_message ]] </p>
                </template>
            </my-component>
        {% endwith %}
    </body>
</html>

There is a lot of other tricks with vuejs and django to make them working great together you can me message if you need.

CallMarl
  • 524
  • 4
  • 15