Usuwanie postów dodanych przez użytkownika. Django

0

Chciałbym aby użytkownik miał możliwość usunięcia dodanego przez siebie posta. Próbuje robić to w ten sposób :

models.py

class PublishedManager(models.Manager):
        def get_queryset(self):
            return super(PublishedManager, self).get_queryset()

class Post(models.Model):
    title = models.CharField(max_length=250)
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    body = models.TextField()
    publish = models.DateTimeField(default=timezone.now)
    location = models.CharField(max_length=100)
    objects = models.Manager()
    published = PublishedManager()
    
    def get_absolute_url(self):
        return reverse('post_detail', args=[self.id])

    def get_absolute_url(self):
        return reverse('delete_post', args=[self.id])

    class Meta:
        ordering = ('-publish',)

views.py

def delete_post(request, id):
    del_post = get_object_or_404(Post, id=id)
    del_post.delete(Post, id=id)
    return render(request, 'account/delete-post.html', {'del_post': del_post})

urls.py

url(r'^delete-post/$', views.delete_post, name='delete_post'),

delete_post.html

{% extends "base.html" %}

{% block title %}Post został usunięty{% endblock %}

{% block content %}
<p>Twój post został usunięty</p>
{% endblock %}

błąd

TypeError: delete_post() missing 1 required positional argument: 'id'

Nie wiem od której strony to ugryźć. Czy błędnie próbuję stworzyć mechanizm usunięcia posta. Czy może del_post.delete() jest niewłaściwe. Czy podaję złe argumenty do .delete(). Proszę o naprowadzenie mnie na dobre tory.

0

Widok delete_post musi dostać id z URLa, więc dodaj odpowiedni pattern w ścieżce, która prowadzi do tego widoku.
get_object_or_404, jak sama nazwa wskazuje, zwróci obiekt lub rzuci wyjątkiem. Jeśli uda się wyciągnąć obiekt, wystarczy wywołać na nim .delete(), bez żadnych parametrów.

Możesz też podejrzeć jak to działa w django adminie - tam link do usuwania przekierowuje na adres w stylu /posts/<id>/delete (GET), tam wyświetla się formularz "Czy jesteś pewny...". Po kliknięciu "Tak" wysyłany jest POST na ten sam URL (/posts/<id>/delete) i jeśli całość przejdzie pomyślnie, na końcu klient dostaje przekierowanie na listę postów (/posts, GET).

0

Dzięki wielkie zadziałało, tylko teraz problem polega na tym że widok delete_post zastępuje widok post_detail. Link który powinien prowadzić do widoku szczegółowego postu usuwa go. Problem może leżeć w tym że te dwie funkcje są do siebie podobne. Obie korzystają z get_absolute_url i get_object_or_404.

views.py

def post_detail(request, id):
    post = get_object_or_404(Post, id=id)
    return render(request, 'account/detail.html', {'post': post})

def delete_post(request, id):
    del_post = get_object_or_404(Post, id=id)
    del_post.delete()
    return render(request, 'account/delete_post.html', {'del_post': del_post})

models.py

def get_absolute_url(self):
        return reverse('post_detail', args=[self.id])

    def get_absolute_url(self):
        return reverse('delete_post', args=[self.id])

urls.py

url(r'^(?P<id>\d+)/$', views.post_detail, name='post_detail'),
url(r'^(?P<id>\d+)/delete-post/$', views.delete_post, name='delete_post'),

dashboard.html

{% extends "base.html" %}


{% block title %}Panel główny{% endblock %}

{% block content %}
  <h1>Panel główny</h1>
  <p>Witaj w panelu głównym</p>

{% for post in posts %}
<ul>
   <li>
   <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
   <p class="date">
    Opublikowany {{ post.publish }} przez {{ post.author }}
   <p>
<p>{{ post.id }}</p>
   </li>
</ul>
<p><a href="{% url "new_post" %}">Dodaj nowe zlecenie</a></p>
 
 {% endfor %}
{% endblock %}

0

UWAGA! Twój widok delete_post nie filtruje zapytania w żaden sposób tylko po ID. Oznacza to, że każdy użytkownik może usunąć posta dowolnego użytkownika. Musisz przefiltrować np. czy post należy do użytkownika.

Co do tego, że widok detail to teraz delete. To nie tak.
get_absolute_url To powinien być link do detail a nie delete. Link do delete musisz sam stworzyć w szablonie za pomocą {% url 'post_delete' id %}

0

Moje wypociny:

def delete_post(request, id):
    del_post = get_object_or_404(Post, id=id)
    if del_post.author == request.user:
        del_post.delete()
    return render(request, 'account/delete_post.html', {'del_post': del_post})

i link

<a href="{% url 'delete_post' id %}">Usuń post</a>

wywala

NoReverseMatch at /account/your-posts/
Reverse for 'delete_post' with arguments '('',)' not found. 1 pattern(s) tried: ['account/(?P<id>\\d+)/delete-post/$']

chyba źle konstruuje link

1
del_post = get_object_or_404(Post, id=id)
    if del_post.author == request.user:
        del_post.delete()

To można zrobić jeszcze lepiej. del_post = get_object_or_404(Post, id=id, author=request.user). I if już niepotrzebny. To id to podałem jako przykład. Tam musi być po prostu id obiektu.

0

Cały czas wywala to samo... :(

NoReverseMatch at /account/your-posts/
Reverse for 'delete_post' with arguments '('',)' not found. 1 pattern(s) tried: ['account/(?P<id>\\d+)/delete-post/$']
1

Po co zgadujesz? Gdzie masz ID posta? W zmiennej post, którą tworzysz przy iteracji. Do niej masz się odwołać a nie do del_post jak wprowadził Cie w błąd użytkownik @iksde

0

Wszystko działa. Dzięki wszystkim za poświęcony mi czas! :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1