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