How to add a form in an html page in django - django

I want to add comments form a specific html which has it's own views and models and I do not want to create a new html file like comment.html which will only display the form and its views. I want users to be able to comment right underneath a post, so that users don't have to click a button such as "add comment" which will take them to a new page with the "comment.form" and then they can comment. Basically want a page with all transfer news and their respective comments as well as a comment-form under the old comment. But I'm stuck. I can add comments manually from the admin page and it's working fine, but it seems that I have to create another url and html file to display the comment form and for users to be able to add comments(btw I'm trying to build a sports related website). Thanks in advance!
My models.py:
class Transfernews(models.Model):
player_name = models.CharField(max_length=255)
player_image = models.CharField(max_length=2083)
player_description = models.CharField(max_length=3000)
date_posted = models.DateTimeField(default=timezone.now)
class Comment(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
transfernews = models.ForeignKey(Transfernews, related_name="comments", on_delete=models.CASCADE)
body = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s - %s' % (self.transfernews.player_name, self.user.username)
My forms.py :
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('body', 'transfernews')
My views.py :
def addcomment(request):
model = Comment
form_class = CommentForm
template_name = 'transfernews.html'
def transfer_targets(request):
transfernews = Transfernews.objects.all()
form = CommentForm(request.POST or None)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.user = request.user
new_comment.save()
return redirect('transfernews/')
return render(request, 'transfernews.html', {'transfernews': transfernews})
My urls.py:
path('transfernews/', views.transfer_targets, name='transfernews'),
My transfernews.html:
<h2>Comments...</h2>
{% if not transfernew.comments.all %}
No comments Yet...
{% else %}
{% for comment in transfernew.comments.all %}
<strong>
{{ comment.user.username }} - {{ comment.date_added }}
</strong>
<br/>
{{ comment.body }}
<br/><br/>
{% endfor %}
{% endif %}
<hr>
<div>Comment and let us know your thoughts</div>
<form method="POST">
{% csrf_token %}
<input type="hidden" value="{{ transfernew.id}}">
<div class="bg-alert p-2">
<div class="d-flex flex-row align-items-start"><textarea class="form-control ml-1 shadow-none textarea"></textarea></div>
<div class="mt-2 text-right"><button class="btn btn-primary btn-sm shadow-none" type="submit">
Post comment</button><button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">Cancel</button></div>
</div>
</div>
</form>

Here's how you can do it :
First, add a field in your CommentForm :
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('body', 'transfernews')
Then in your template, you can set an hidden input in the form to link the comment to the transfernews :
{% if form.errors %}
<p>There are errors in your form :</p>
<ul>{{ form.errors }}</ul>
{% endif %}
<form method="POST">
{% csrf_token %}
{# Add this next line #}
<input type="hidden" value="{{ transfernew.id}}">
<div class="bg-alert p-2">
<div class="d-flex flex-row align-items-start">
<textarea class="form-control ml-1 shadow-none textarea" name="body"></textarea>
</div>
<div class="mt-2 text-right">
<button class="btn btn-primary btn-sm shadow-none" type="submit">Post comment</button>
<button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">Cancel</button>
</div>
</div>
</form>
Then in your view :
def transfer_targets(request):
transfernews = Transfernews.objects.all()
form = CommentForm(request.POST or None)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.user = request.user
new_comment.save()
return redirect('transfernews')
return render(request, 'transfernews.html', {
'transfernews': transfernews,
'form': form
})

Related

django form errors not showing on template

I'm using the basic django registration form and I'm not getting any errors displayed. I've seen a bunch of answers and nothing is working for me. I'm not sure if it's because I have custom css for the page or bootstrap or something else. Basically how do I display the errors in this particular case.
Here's my form:
<div class="form-content">
<h1>Sign Up</h1>
{% if user.is_authenticated == False %}
<form method="POST">
{% csrf_token %} {{form.as_p}}
<button class="btn form-btn">Sign Up</button>
<h4><span>or</span></h4>
<a
class="btn google-btn"
href="{% provider_login_url 'google' %}"
role="button"
style="text-transform: none; width: 100%"
>
<img
width="20px"
style="margin-bottom: 3px; margin-right: 5px"
alt="Google sign-in"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/512px-Google_%22G%22_Logo.svg.png"
/>
Sign up with Google
</a>
</form>
{% else %}
<p>You're already registered...</p>
{% endif %}
</div>
Here's my view:
class UserRegistration(generic.CreateView):
form_class = RegisterForm
template_name = 'registration/registration.html'
def form_valid(self, form):
user = form.save()
form.registration_notification()
login(self.request, user, backend='django.contrib.auth.backends.ModelBackend')
return redirect(self.request.GET.get('next'))
and form:
class RegisterForm(UserCreationForm):
email = forms.EmailField()
first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')
def registration_notification(self):
email = self.cleaned_data['email']
username = self.cleaned_data['username']
if self.is_valid():
registration_notification_task.delay(email, username)
I'm not sure where to return the errors or where to validate the form and no answers for other questions have helped my situation. Now when I submit an invalid form there are no errors the page just doesn't submit. There's not even an error in the network tab so it's probably happening on the html side.
Updating my post following comments below:
**forms.py** (dont forget the import bit)
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
class RegisterForm(UserCreationForm):
class Meta:
model = User
fields = ["username", "email", "password1", "password2",]
views.py
def register_user(request):
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
new_user = form.save()
new_user = authenticate(username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],)
login(request, new_user)
messages.success(request,("Registration succesful!"))
return HttpResponseRedirect("/home")
else:
form = RegisterForm()
return render(request,'main/registration/register_user.html',{'form':form})
registration template
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-5 mx-auto">
<div id="second">
<div class="myform form ">
<div class="logo mb-3">
<div class="col-md-12 text-center">
<h1 >Signup</h1>
</div>
</div>
<form method="POST" action = "{% url 'register_user' %}" class="form-group">
{% csrf_token %}
{{ form| crispy }}
<div class="col-md-12 text-center mb-3">
<button type="submit" class=" btn btn-block mybtn btn-primary tx-tfm">Let's do it!</button>
</div>
<div class="col-md-12 ">
<div class="form-group">
<p class="text-center">Already have an account?</p>
</div>
</div>
</div>
</form>
</div>
</div>
{% endblock %}

I want to make reply to comments feature in Django

I have a simple project and I added a comment feature there. Now I want to add comment reply feature. When I write and send the answer, it registers to sql but I cannot show it on the frontend.
models.py
class Comments(models.Model):
comment_author = models.ForeignKey(ArticleForm, on_delete=models.CASCADE, related_name='comments')
commenter_name = models.ForeignKey(User, on_delete=models.CASCADE)
comment_content = models.TextField()
commented_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "'{}' commented by '{}'".format(self.comment_content, self.commenter_name)
class Meta:
ordering = ['-commented_date']
class ReplyComment(models.Model):
reply_comment = models.ForeignKey(Comments, on_delete=models.CASCADE, related_name='replies')
replier_name = models.ForeignKey(User, on_delete=models.CASCADE)
reply_content = models.TextField()
replied_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "'{}' replied with '{}' to '{}'".format(self.replier_name,self.reply_content, self.reply_comment)
views.py
def detail(request,id):
article = get_object_or_404(ArticleForm,id=id)
comments = article.comments.all()
return render(request, 'detail.html', {'article': article, 'comments': comments})
def replyComment(request,id):
comments = Comments.objects.get(id=id)
if request.method == 'POST':
replier_name = request.user
reply_content = request.POST.get('reply_content')
newReply = ReplyComment(replier_name=replier_name, reply_content=reply_content)
newReply.reply_comment = comments
newReply.save()
messages.success(request, 'Comment replied!')
return redirect('index')
detail.html
<div class="container">
<a type="text" data-toggle="collapse" data-target="#reply{{comment.id}}" style="float: right;" href="">Reply</a><br>
{% if replies %}
{% for reply in replies %}
<div>
<div class="fw-bold"><small><b>Name</b></small></div>
<div style="font-size: 10px;">date</div>
<small>Reply comment</small><br>
</div>
{% endfor %}
{% endif %}
<div id="reply{{comment.id}}" class="collapse in">
<form method="post" action="/article/reply/{{comment.id}}">
{% csrf_token %}
<input name="replier_name" class="form-control form-control-sm" type="hidden">
<input name="reply_content" class="form-control form-control-lg" type="text" placeholder="Reply comment">
<button type="submit" class="btn btn-primary" style="float: right; margin-top: 5px;">Reply</button>
</form>
</div>
What I'm trying to do is pull the responses from the sql and show them below the comment
I will be glad if you can tell me a solution suitable for my codes. Thanks
Perhaps this will work:
{% for comment in comments %}
<div>{{ comment }}</div>
{% for reply in comment.replycomment_set.all %}
<div>
<div class="fw-bold"><small><b>Name {{ reply.replier_name }}</b></small></div>
<div style="font-size: 10px;">date {{ reply.replied_date }}</div>
<small>Reply comment {{ reply.content }}</small><br>
</div>
{% endfor %}
{% endfor %}

Can I add a form in django in HTML

I want to add comments form a specific html which has it's separate views and models and I don't want to create a new form.html just to display the form and its views. But I'm stuck. I can add comments manually from the admin page and it's working fine, but it seems that I have to create another url and html file to display the comment form and for users to be able to add comments(btw I'm trying to build a sports related website). Thanks in advance!
My models.py:
class Transfernews(models.Model):
player_name = models.CharField(max_length=255)
player_image = models.CharField(max_length=2083)
player_description = models.CharField(max_length=3000)
date_posted = models.DateTimeField(default=timezone.now)
class Comment(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
transfernews = models.ForeignKey(Transfernews, related_name="comments", on_delete=models.CASCADE)
body = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s - %s' % (self.transfernews.player_name, self.user.username)
My forms.py :
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('body',)
My views.py :
def addcomment(request):
model = Comment
form_class = CommentForm
template_name = 'transfernews.html'
My urls.py:
path('comment/', views.addcomment, name='comment'),
My transfernews.html:
<h2>Comments...</h2>
{% if not transfernew.comments.all %}
No comments Yet...
{% else %}
{% for comment in transfernew.comments.all %}
<strong>
{{ comment.user.username }} - {{ comment.date_added }}
</strong>
<br/>
{{ comment.body }}
<br/><br/>
{% endfor %}
{% endif %}
<hr>
<div>Comment and let us know your thoughts</div>
<form method="POST">
{% csrf_token %}
<div class="bg-alert p-2">
<div class="d-flex flex-row align-items-start"><textarea class="form-control ml-1 shadow-none textarea"></textarea></div>
<div class="mt-2 text-right"><button class="btn btn-primary btn-sm shadow-none" type="submit">
Post comment</button><button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">Cancel</button></div>
</div>
</div>
</form>
You don't have to.
In your HTML, take out the anchor tag, you only need the submit button.
<form method="POST">
{% csrf_token %}
<div class="bg-alert p-2">
<div class="d-flex flex-row align-items-start">{{ form.body }}</div>
<div class="mt-2 text-right"><button class="btn btn-primary btn-sm shadow-none" type="submit">
Post comment</button><button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">Cancel</button></div>
</div>
In your views.py, do this.
def view_that_loads_the_page(request, news_id):
news = Transfernews.objects.get(id=news_id)
form_class = CommentForm(request.POST or None)
if form_class.is_valid():
# save both news and logged in user
form.instance.transfernews = news
form.instance.user = request.user
# save form.
form_class.save()
# returns to the same page
return HttpResponseRedirect(request.path_info)
return render(request, "your_html.html", {"form" : form_class})

How to insert multiple choices in to the database and display

My models is:
class LabRequest(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
lab_test = models.ManyToManyField(Lab)
My Form
class LabRequestModelForm(forms.ModelForm):
class Meta:
model = LabRequest
fields = ['ticket', 'lab_test']
widgets = {
'lab_test': forms.CheckboxSelectMultiple,
}
My view
def LabRequestToGenerateView(request):
if form.is_valid():
obj = form.save(commit=False)
obj.created_by = request.user.id
obj.save()
return render(request, 'dashboard/laboratory_request.html', {'form': form})
My Template
<form action="." method="POST">
{% csrf_token %}
{{ form.as_p }}
<div class="form-group float-right">
<button type="submit" name="submit" class="btn btn-success btn-sm" > <i
class="fa fa-save"></i>
Save</button>
</div>
</form>
{% for rl in rl %}
<label for=""> Ticket: {{ rl.ticket }} </label>
<p> Lab Tests: {{ rl.lab_test }}</p>
{% endfor %}
So, It's displaying as a checkbox that's good. but when i want to save some data it saves only ticket, not lab_test? So, how do I save both?
As you see it displays only ticket which is Ubed Gedi ALi and where I wanted to see lab_test it shows me appname.modelname.None

How add follow button to profile in django getstream

I try to add follow button in django with Getstream.io app.
Following the getstream tutorial, django twitter, I managed to create a list of users with a functioning follow button as well as active activity feed. But when i try add follow button on user profile page, form send POST but nothing happends later.
I spend lot of time trying resolve this, but i'm still begginer in Django.
Code:
Follow model:
class Follow(models.Model):
user = models.ForeignKey('auth.User', related_name = 'follow', on_delete = models.CASCADE)
target = models.ForeignKey('auth.User', related_name ='followers', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add = True)
class Meta:
unique_together = ('user', 'target')
def unfollow_feed(sender, instance, **kwargs):
feed_manager.unfollow_user(instance.user_id, instance.target_id)
def follow_feed(sender, instance, **kwargs):
feed_manager.follow_user(instance.user_id, instance.target_id)
signals.post_delete.connect(unfollow_feed, sender=Follow)
signals.post_save.connect(follow_feed, sender=Follow)
Views:
def user(request, username):
user = get_object_or_404(User, username=username)
feeds = feed_manager.get_user_feed(user.id)
activities = feeds.get()['results']
activities = enricher.enrich_activities(activities)
context = {
'user': user,
'form': FollowForm(),
'login_user': request.user,
'activities': activities,
}
return render(request, 'profile/user.html', context)
def follow(request):
form = FollowForm(request.POST)
if form.is_valid():
follow = form.instance
follow.user = request.user
follow.save()
return redirect("/timeline/")
def unfollow(request, target_id):
follow = Follow.objects.filter(user=request.user, target_id=target_id).first()
if follow is not None:
follow.delete()
return redirect("/timeline/")
Forms:
class FollowForm(ModelForm):
class Meta:
exclude = set()
model = Follow
Urls:
path('follow/', login_required(views.follow), name='follow'),
path('unfollow/<target_id>/', login_required(views.unfollow), name='unfollow'),
And user.html
<form action="{% if request.user in User.followers.all %}{% url 'unfollow' target.id %}{% else %}{% url 'follow' %}{% endif %}" method="post">
{% csrf_token %}
<input type="hidden" id="id_target" name="target" value="{{target.id}}">
<input type="hidden" id="id_user" name="user" value="{{user.id}}">
<button type="submit" class="btn btn-primary btn-sm" value="Create" />
{% if request.user in User.followers.all %}
Unfollow
{% else %}
Follow
{% endif %}
</button>
</form>
This form work in list user page:
{% for one, followed in following %}
<div class="col-md-3 col-sm-6 col-xs-12">
<div class="card">
<div class="card-body">
{% include "profile/_user.html" with user=one %}
<form action="{% if followed %}{% url 'unfollow' one.id %}{% else %}{% url 'follow' %}{% endif %}" method="post">
{% csrf_token %}
<input type="hidden" id="id_target" name="target" value="{{one.id}}">
<input type="hidden" id="id_user" name="user" value="{{user.id}}">
<button type="submit" class="btn btn-primary btn-sm" value="Create" />
{% if followed %}
Przestań obserwować
{% else %}
Obserwuj
{% endif %}
</button>
</form>
</div>
</div>
</div>
{% if forloop.counter|divisibleby:'4' %}
<div class="clearfix visible-sm-block visible-md-block visible-lg-block"></div>
{% elif forloop.counter|divisibleby:'2' %}
<div class="clearfix visible-sm-block"></div>
{% endif %}
{% endfor %}
</div>
And user list Views.py
def discover(request):
users = User.objects.order_by('date_joined')[:50]
login_user = User.objects.get(username=request.user)
following = []
for i in users:
if len(i.followers.filter(user=login_user.id)) == 0:
following.append((i, False))
else:
following.append((i, True))
login_user = User.objects.get(username=request.user)
context = {
'users': users,
'form': FollowForm(),
'login_user': request.user,
'following': following
}
return render(request, 'uzytkownicy.html', context)