简体   繁体   中英

Why can't I remove the member from the list and delete their interest?

Every blogpost has their own members. To become a member, the interest you submit must be accepted. i am trying to build a remove member function whereby if you are a member, you can remove yourself from the list and if you are the blog_post.author, you can remove ANYONE except yourself (because to remove yourself you need to delete the blogpost entirely.

Once you are removed from the member-list, I also want the initial interest they have submitted to be deleted. I have attached my models.py, urls.py, template.html and views.py in this question. First, i am getting no errors, but I'm unsure of why the interest is not deleted and the member is also not removed. Is there anything wrong with my code?

So basically nothing happens and when i press on the remove button, i get redirected to my details page as shown in my last view sentence.

Few possibilities:

  1. I queried the slug wrongly in my template
  2. my if and or statement in views.py is wrong
  3. my try statement in views.py is wrong

models.py

class Account(AbstractBaseUser):
 email                  = models.EmailField(verbose_name="email", max_length=60, unique=True)
 username               = models.CharField(max_length=30, unique=True)

class BlogPost(models.Model):
 title                  = models.CharField(max_length=50, null=False, blank=False, unique=True)
 author                     = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
 slug                   = models.SlugField(blank=True, unique=True)
 members    = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name="members")

class Interest(models.Model):
   user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
   blog_post = models.ForeignKey(BlogPost, on_delete=models.CASCADE)

class InterestInvite(models.Model):

   ACCEPT = "ACCEPT"
   DECLINE = "DECLINE"
   PENDING = "PENDING"
   STATUS_CHOICES = [
      (ACCEPT, "accept"),
      (DECLINE, "decline"),
      (PENDING, "pending"),

   ]

   interest = models.OneToOneField(Interest, on_delete=models.CASCADE, related_name="interest_invite")   
   status = models.CharField(max_length=25, choices=STATUS_CHOICES, default=PENDING)

views.py

class InterestMixin(object):
    model=Interest

class BlogPostMixin(object):
    model=BlogPost

class MemberListView(UserPassesTestMixin, BlogPostMixin, DetailView):
    template_name = "HomeFeed/membersof_yourpost.html"
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        blog_post=self.get_object()
        context['blog_post'] = blog_post
        return context


def remove_member_view(request, slug):
    user = request.user
    blog_post = get_object_or_404(BlogPost, slug=slug)
    if request.method == "POST":
        user_id = request.POST.get("user_id")
        if (user_id == user.pk and blog_post.members.filter(pk=user.pk).exists()) or (blog_post.author == request.user and user.pk != user_id):
            try:
                removee = Account.objects.get(pk=user_id)
                blog_post.members.remove(removee)
                Interest.objects.filter(user=removee, blog_post=blog_post).delete()
            except Account.DoesNotExist:
                pass
    return redirect('HomeFeed:detail', slug=slug)


urls.py

    path('<user_id>/', account_view, name="view"),
    path("blog/<pk>/<slug>/member-list/", MemberListView.as_view(), name="member_list"),
    path("removemember/<slug>/", remove_member_view, name="remove_member"),

members.html

    {% for member in object.members.all %}
    {% if member == request.user %}
    <li class="text-center"><a class="btn btn-info btn-sm mt-3 mb-3" href="{% url 'account:view' member.pk %}">This is you</a></li>
    {% else %}
    <li class="text-center"><a class="btn btn-primary btn-sm mt-3 mb-3" href="{% url 'account:view' member.pk %}">{{member.username}}</a></li>
    {% endif %}

        <form method="POST" action="{% url 'HomeFeed:remove_member' object.slug %}">
            {% csrf_token %}
            <button class="btn btn-sm btn-danger">Remove</button>
        </form> 


    {% endfor %}

Your class BlogPost relate ManyToManyField with settings.AUTH_USER_MODEL but in your remove_member_view function, you query with Account .

if (user_id == user.pk and blog_post.members.filter(pk=user.pk).exists()) or (blog_post.author == request.user and user.pk != user_id):
            try:
                removee = Account.objects.get(pk=user_id) #<== here
                blog_post.members.remove(removee)
                Interest.objects.filter(user=removee, blog_post=blog_post).delete()
            except Account.DoesNotExist:
                pass

Besides, I can not understand what is the purpose of user_id , no user_id was shown in html to be sent with POST request, which may lead to not execute the if condition:

Update You can try this:

from django.contrib.auth import get_user_model

User = get_user_model()

removee= User.objects.get(pk=user_id)

And change the if statement as Abdul recommended above.

You are not posting any user_id to your view. Try this:
In your template:

<form method="POST" action="{% url 'HomeFeed:remove_member' object.slug %}">
    {% csrf_token %}
    <input type="number" name="user_id" value="{{ member.id }}" hidden>
    <button class="btn btn-sm btn-danger">Remove</button>
</form>

Also in your view the condition is a bit wrong, change it to:

if blog_post.author.id != user_id and blog_post.members.filter(pk=user_id).exists() and (user_id == user.pk or blog_post.author == user)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM