Usuwanie postów dodanych przez użytkownika. Django

Usuwanie postów dodanych przez użytkownika. Django
N2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7
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

Kopiuj
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

Kopiuj
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

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

delete_post.html

Kopiuj
{% extends "base.html" %}

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

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

błąd

Kopiuj
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.

IK
  • Rejestracja: dni
  • Ostatnio: dni
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).

N2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7
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

Kopiuj
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

Kopiuj
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

Kopiuj
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

Kopiuj
{% 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 %}

AN
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 988
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 %}

N2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7
0

Moje wypociny:

Kopiuj
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

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

wywala

Kopiuj
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

AN
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 988
1
Kopiuj
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.

N2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7
0

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

Kopiuj
NoReverseMatch at /account/your-posts/
Reverse for 'delete_post' with arguments '('',)' not found. 1 pattern(s) tried: ['account/(?P<id>\\d+)/delete-post/$']
AN
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 988
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

N2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7
0

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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.