Obtaining individual post id

Viewed 144

I am building a copy of a social network with Django and Vanilla JS. I would like to edit posts asynchronously using the fetch API.

In urls.py I've got an API route as follows:

urlpatterns = [
...
path("edit/<int:post_id>", views.edit, name="edit"), 
...
]

In models.py the Post objects is as follows:

    class Post(models.Model):
        user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="posts")
        date_posted = models.DateTimeField(default=timezone.now)
        content = models.TextField()
        likes = models.IntegerField(default=0)

        def __str__(self):
            return f"{self.user.username} added a new post"

        def serialize(self):

            return {
             "id": self.id,
             "user": self.user,
             "date_posted": self.date_posted.strftime("%b %d %Y, %I:%M %p"),
             "content": self.content,
             "likes": self.likes}

In views.py, the edit route is as follows, for now:

@login_required
@csrf_exempt
def edit(request,post_id):
    try:
        post = Post.objects.get(user=request.user, pk=post_id)
    except Email.DoesNotExist:
        return JsonResponse({"error": "Post not found"}, status=404)

    if request.method == "GET":
        return JsonResponse(post.serialize())

According to the assignment specs, only users who authored the post can edit it. In index.html appear all the posts and the edit button where applicable.

...
{% for post in posts %}
<h3 class="border border-secondary rounded"><a href="{% url 'profile' post.user.id %}">{{ post.user.username }}</a>
</h3>
<hr>
<div class="border border-primary rounded mb-4">
    <div id="post-{{post.id}}">
        <p>{{ post.content }}</p>
        <p><small>{{ post.date_posted }}</small></p>
    </div>

    {% if user.username != post.user.username %}
    <button class="btn btn-sm btn-outline-secondary" id="like_btn">&heartsuit; <span class="ml-1">{{ post.likes }}
        </span></button>
    {% else %}
    <p> <small>{{ post.likes }} likes </small> </p>
    {% endif %}
    {% if post.user.id == request.user.id %}
    <button class="btn btn-primary btn-sm" id="edit_btn-{{post.id}}">Edit</button>
    {% endif %}
</div>
{% endfor %}
...

Finally, I would like to add functionality to edit posts through a PUT request.

script.js contains all the JS functions for this project. For now all I would like my function to do is log to the console a message saying that I've clicked on the appropriate post to be edited

script.js

document.addEventListener('DOMContentLoaded', () => {
...
document.querySelector(`#edit_btn-${id}`).addEventListener('click', () => {
    edit();
  })
});
...
function edit(post) {
fetch(`/edit/${post.id}`)
.then((response) => response.json())
.then((post) => console.log(`Editing post ${post.id}...`));

In the console, I get the following message when I click on the edit button:

Uncaught ReferenceError: id is not defined
at HTMLDocument.<anonymous> (script.js:10)

where line 10 in script.js is when I make the function call.

I am confused as to what might be causing this error. Any help would be greatly appreciated. Thank you.

1 Answers

You need to use a better way to get id.

For example in your for-loop you can use

{% if post.user.id == request.user.id %}
<button class="btn btn-primary btn-sm" onclick="edit({{post.id}})">Edit</button>
{% endif %}

In your js you can use this

function edit(id) {
    fetch(`/edit/${id}`)
     .then((response) => response.json())
     .then((post) => console.log(`Editing post ${id}...`));
}
Related