Custom Django forms within template and hidden inputs - django

Very, very quick question. I'm rendering my own custom forms within my html template...how would I go about submitting the hidden input when the user submits that form?
template.html
<form class="contact-form" name="contact-form" method="post" action=".">
{% csrf_token %}
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label for="four">Your Text</label>
<textarea class="form-control" type="text" name="{{ comment_form.content.name }}" {% if comment_form.content.value %}value="{{ comment_form.content.value }}"{% endif %} placeholder="" required="required" id="four"></textarea>
</div>
</div>
</div>
<div class="form-group text-center">
<button type="submit" class="btn btn-primary pull-right">Submit Comment</button>
</div>
</form>
form.py
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
content_type = forms.CharField(widget=forms.HiddenInput)
object_id = forms.IntegerField(widget=forms.HiddenInput)
#parent_id = forms.IntegerField(widget=forms.HiddenInput, required=False)
content = forms.CharField(widget=forms.Textarea)
class Meta:
model = Comment
fields = ('content',)

You can add this part to you forms.py file (in CommentForm class) :
hidden_field=forms.CharField(widget=forms.HiddenInput())
I hope it will work.let me know

Related

How do I use Django generic updateviews to update my model using individual form field values?

models.py:
from django.db import models
class Location(models.Model):
name = models.CharField(max_length=20)
is_source = models.BooleanField(default=False)
is_destination = models.BooleanField(default=False)
def __str__(self):
return self.name
views.py
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views import generic
from .models import Location
class LocationsListView(generic.ListView):
model = Location
template_name = 'locations/list.html'
context_object_name = 'locations'
class LocationUpdateView(generic.edit.UpdateView):
model = Location
fields = ['name', 'is_source', 'is_destination']
context_object_name = 'location'
template_name = 'locations/update.html'
success_url = reverse_lazy('locations:list')
class LocationDeleteView (generic.edit.DeleteView):
model = Location
template_name = 'locations/confirm_delete.html'
context_object_name = 'location'
success_url = reverse_lazy('locations:list')
locations/update.html
{% extends 'base.html' %}
{% block title %}Location Update{% endblock %}
{% block content %}
<section>
<div class="container">
<h1>Location Update</h1>
<div class="form-container">
<form method="post">
{% csrf_token %}
{% if form.errors %}
<div class="p-3 mb-3 border border-danger border-3 rounded">{{ form.errors }}</div>
{% endif %}
<div class="mb-3">
<label for="" class="form-label">Name</label>
<input type="text" class="form-control" value="{{ form.name.value }}">
</div>
<div class="mb-3">
<input type="checkbox" class="form-check-input" {% if form.is_source.value %} checked {% endif %}>
<label for="">Source</label>
</div>
<div class="mb-3">
<input type="checkbox" class="form-check-input" {% if form.is_destination.value %} checked {% endif %}>
<label for="">Destination</label>
</div>
<input type="submit" class="btn btn-success mb-3" value="Save">
</form>
</div>
</div>
</section>
{% endblock %}
locations.urls.py
from django.urls import path
from . import views
app_name = 'locations'
urlpatterns = [
path('', views.LocationsListView.as_view(), name='list'),
path('update/<int:pk>/', views.LocationUpdateView.as_view(), name='update'),
path('delete/<int:pk>/', views.LocationDeleteView.as_view(), name='delete'),
]
When I try to update my model, individually rendering the form fields using {{form.name.value}}, I get an error that my name field is required, and yet it is filled. I do not get the error if I render the form as a whole using {{form.as_p}} for example. What am I doing wrong?
I tried using {{form.as_p}} and it worked. But I need individual field rendering so I can style my form.
You need to provide the name attribute for each of your field <input> tags. The field's html_name attribute should be used if rendering manually
<input name="{{ form.name.html_name }}" type="text" class="form-control" value="{{ form.name.value }}">

How to output fields to html template correctly from User model in Django ORM?

Task: Create a Django SQL query, pulling out only the required fields. Submit them to the template.
I have a Post model with a foreign key to a standard User model:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
text = models.TextField()
pub_date = models.DateTimeField("date published", auto_now_add=True)
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="posts"
)
Here is the required fragment in the HTML template, where you need to insert the author's name:
{% for post in posts %}
<h3>
Author: {{ post.author.first_name }}, Date: {{ post.pub_date|date:'d M Y' }}
</h3>
view function:
from django.shortcuts import render
from .models import Post
def index(request):
latest = (
Post
.objects
.order_by('-pub_date')[:10]
.select_related('author')
.values('pub_date', 'author__first_name')
)
return render(request, 'index.html', {'posts': latest})
Here's what the page fragment looks like on the local server:
template
And here is the final sql query shown by django debug toolbar:
Query
In the user table, I have one user and all posts are related to him. If I do not use .values in the view, then all the attributes of the author that I request in the template are displayed perfectly (for example, last_name, username, get_full_name()), but then sql requests all the fields of the user table (as it usually does), and I want get only certain ones to save memory. I also tried to recreate the project, use User = get_user_model(). Nothing helped.
You can refer this:
Model
from django.db import models
# Create your models here.
class CoachDetailsModel(models.Model):
coach_id=models.AutoField(primary_key=True)
name=models.CharField(max_length=100,help_text="Enter FullName")
email=models.EmailField(max_length=100,help_text="Enter Email id")
contact=models.BigIntegerField(help_text="Enter Mobile Number" ,null=True)
password=models.CharField(max_length=100,help_text="Enter Password")
coach_status=models.CharField(max_length=100,default='pending',help_text="Enter Password")
def __str__(self):
return self.email
class Meta:
db_table="Coach_details"
Views
def coach_register(request):
if request.method == "POST":
name= request.POST.get('name')
email = request.POST.get('email')
contact = request.POST.get('contact')
password = request.POST.get('password')
CoachDetailsModel.objects.create(name=name,email=email,contact=contact,password=password)
return render(request,'coach/coach-register.html')
### url
path('coach-register',coachviews.coach_register,name='coach_register'),
Html page
<form method="POST" id="contactForm" name="contactForm" class="contactForm" enctype="multipart/form-data">
{% csrf_token %}
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="label" for="subject">Enter UserName</label>
<input type="text" class="form-control" name="name" id="subject" placeholder="UserName">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="label" for="subject">Enter Contact</label>
<input type="text" class="form-control" name="contact" id="subject" placeholder="Contact">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="label" for="subject">EMAIL-ADDRESS</label>
<input type="text" class="form-control" name="email" id="subject" placeholder="Email">
</div>
</div>
<div class="col-md-6">
<div class="form-group-col-6">
<label class="label" for="subject">PASSWORD</label>
<input type="text" class="form-control" name="password" id="subject" placeholder="Password">
</div>
</div>
<div class="col-md-12">
<div class="form-group col-9">
<input type="submit" value="Register" class="btn btn-primary">
<div class="submitting"></div>
</div>
</div>
</div>
</form>

ModelForm is not generating any form

So my problem is that even though I have created the forms from my model and provided my views with those forms, the related template is not displaying any form:
The following is my forms.py :
from django import forms
from django.contrib.auth.models import User
from .models import Account
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField(max_length=100)
class Meta:
model = User
fields = ['username', 'email']
class AccountUpdateForm(forms.ModelForm):
class Meta:
model= Account
fields = ['image']
And the next one is my views.py:
from .forms importUserUpdateForm, AccountUpdateForm
def account(request):
user_update_form = UserUpdateForm()
profile_update_form = AccountUpdateForm()
return render(request, 'blog/profile.html', {
'user_update_form':user_upate_form,
'profile_update_form':profile_update_form
})
But the following template does not show any form
{% extends './base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-12 d-flex flex-column justify-content-center align-items-start">
<img src="{{ user.account.image.url }}" alt="" class="user-profile-pic">
<label for="user-profile-pic-input">Choose an image</label>
<input type="file" class="form-control-files w-100" id="user-profile-pic-input" name='user-profile-pic-input'>
</div>
</div>
<div class="row">
<div class="col-12">
<form method="POST">
{% csrf_token %}
{{ user_update_form }}
{{ profile_update_form }}
<input type="submit" value="Save changes!" class="btn btn-info btn-block">
</form>
</div>
</div>
{% endblock %}
I had this problem just yesterday. It worked when i called the form class without brackets ()
Try this:
user_update_form = UserUpdateForm
profile_update_form = AccountUpdateForm
If this doesn't work you should probably go down the formset path (inlineformset_factory). It's used to connect modelforms linked by a foreign key. It works with one-to-one and one-to-many relationships.

How do i push uploaded image file in my template input for update in django 2.0

I want to open a particular record in html template in update mode for which i want every value which was inserted before for this record be in those field, i got every required value in field for text field but in file field which contains image ,it shows no file selected where as i want the image file name(url) in there.
I havent used django form rather i used normal bootstrap forms.
models.py
from django.db import models
from django.contrib.auth.models import User
class Product(models.Model):
title = models.CharField(max_length=255)
pub_date = models.DateTimeField()
body = models.TextField()
image = models.ImageField(upload_to='images/') # i m facing problem for this field
icon = models.ImageField(upload_to='images/') # i m facing problem for this field as well
url = models.TextField()
votes_total = models.IntegerField(default=1)
hunter = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.title
def summary(self):
return self.body[:100]
def short_pub_date(self):
return self.pub_date.strftime('%b %e %Y')
#
views.py
def myproducts_update(request,product_id):
product = get_object_or_404(Product,pk=product_id)
print(product.image) # this prints the name of the file (images/37003.jpeg)
return render(request,'products/myproducts_update.html',{'product':product})
templates(myproducts_update.html)
{% extends 'base.html' %}
{% block content %}
{% if error %}
{{error}}
{% endif %}
<br>
<br>
<div class="container">
<div class="jumbotron">
<h2>Update Product</h2>
<form action="{% url 'create' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label for="title">Title:</label>
<input type="text" class="form-control" id="email" value={{product.title}} placeholder="please enter title" name="title" required>
</div>
<div class="form-group">
<label for="body">Description:</label>
<input type="text" class="form-control" id="body" value={{product.body}} placeholder="Description" name="body" required>
</div>
<div class="form-group">
<label for="url">URL:</label>
<input type="text" class="form-control" id="url" value={{product.url}} placeholder="please enter url" name="url" required>
</div>
<br>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="icon">
<strong>Icon:</strong></label>
<input type="file" id="icon" name="icon" value={{product.icon}} required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="url">
<strong>Image:</strong></label>
<input type="file" id="image" placeholder="please enter url" name="image" value={{product.image}} required>
</div>
</div>
</div>
<br>
<input type="submit" value="Update Product" class="btn btn-primary">
</form>
</div>
</div>
{% endblock %}
Link which contains image of form where i have problem
I am having trouble in getting the url of the image in the templates,guys please help me
Thanks in advance!
Try something like this in your <form>:
<div class="margintop50px">
<img {% if object.image %} src="{{ object.image.url }}" {% else %} alt="You have no image." {% endif %}>
<input type="file" name="image" accept="image/*">
</div>
UPDATE:
I just checked your views.py. Sorry for not noticing sooner, but your myproducts_update() function never .save()'s anything, so nothing will show because of that. Try changing that function to something like the following. It assumes the product has already been created somewhere else because I don't know of any other views you made to get this far (maybe you originally added all pics/text from the admin panel? And personally, I would change the names of your function(s) because your form goes to 'create', but the function you showed states that this is about updating it, and that's generally not a clear path to follow when designing it because createing something is different from 'update'ing it. So if the following still doesn't work, I'll need to see your 'create' view, and the urlpatterns for all these functions).
Either way, there are better ways to improve the following (such as what I talked about above), but this is all I can give you without knowing that stuff:
views.py
def myproducts_update(request,product_id):
product = get_object_or_404(Product,pk=product_id)
if request.method == 'POST':
product.body = request.POST.get('body', False)
product.title = request.POST.get('title', False)
product.url = request.POST.get('url', False)
product.icon = request.FILES.get('icon', False)
product.image = request.FILES.get('image', False)
product.save()
return render(request,'products/myproducts_update.html',{'product':product})
And then use the example template above to get it to show on that page.

Using Django registration with a Flat UI template

I have created a template design for signup page using Flat UI. Now i want to use Django registration to register a user. I have goggled various resources but they are very complex and using Django inbuilt form to create a form.
I need simple steps that i can follow
signup.html(home/django/mysite/templates)
{% extends "base.html" %}
{% block title %}Signup page{% endblock %}
{% block content %}
<div class="container" style="width:500px">
<h3 style="margin-top:100px">Sign Up</h3>
<hr>
<div class="login-form">
<form action="" method="post">
<div class="control-group span3" style="width:400px" >
<input type="text" value="" placeholder="Enter your name" id="name" style="width:400px;padding-bottom:15px;margin-bottom:10px" >
<i class="input-icon fui-user" for="login-name"></i>
</div>
<div class="control-group span3" style="width:400px" >
<input type="text" value="" placeholder="Your E-mail" id="email" style="width:400px;padding-bottom:15px;margin-bottom:10px" >
<i class="input-icon fui-mail" for="login-name"></i>
</div>
<div class="control-group span3" style="width:400px">
<input type="password" value="" placeholder="Password" id="pass" style="width:400px;padding-bottom:15px;margin-bottom:10px">
<i class="input-icon fui-lock" for="login-pass"></i>
</div>
<div class="control-group span3" style="width:400px">
<input type="password" value="" placeholder="Confirm Password" id="login-pass" style="width:400px;padding-bottom:15px;margin-bottom:10px">
<i class="input-icon fui-lock" for="login-pass"></i>
</div>
<div style="text-align:center">
<a class="btn btn-hg btn-primary btn-wide" href="#">Sign Up</a>
<!--<a class="login-link" href="#">Lost your password ?</a> -->
</div>
</form>
</div><!-- /login-form -->
</div> <!-- /container -->
{% endblock content %}
views.py
def signup(request):
return render(request, 'signup.html')
urls.py
urlpatterns = patterns('',
url(r'^signup/$', views.signup),)
What i should write in views.py or models.py to register a user using django registration.
You can use django registration together with custom html/css through django forms. Here are the steps:
Provided you have included relevant imports, your urls.py looks fine so no changes needed.
Create a forms.py file in the same folder as your views.py and add the following code into forms.py:
from django import forms
class Signup_form(forms.Form):
# CSS styles should not be inline. i've moved your style contents under a 'form-control' class
name = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'type':'text', 'placeholder':'Enter your name', 'id':'name', 'name':'name', 'class' : 'form-control'}))
email = forms.EmailField(label="Email address", widget=forms.TextInput(attrs={'type':'text', 'placeholder':'Your E-mail', 'id':'email', 'name':'email', 'class' : 'form-control'}))
pass1 = forms.CharField(max_length = 20, widget=forms.TextInput(attrs={'type':'password', 'placeholder':'Password', 'id':'pass1', 'name':'pass1', 'class' : 'form-control'}))
pass2 = forms.CharField(max_length = 20, widget=forms.TextInput(attrs={'type':'password', 'placeholder':'Confirm Password', 'id':'pass2', 'name':'pass2', 'class' : 'form-control'}))
3.In your views.py file, you have to link pass the Signup_form to your views layer. Change your views.py file to the following:
from forms import Signup_form
def signup(request):
form = Signup_form()
name = request.POST.get('name','')
email = request.POST.get('email', '')
pass1 = request.POST.get('pass1', '')
pass2 = request.POST.get('pass2', '')
# Do some validations here
user = User.objects.create_user(name, email, pass2)
if user:
user.save()
return render(request, 'signup.html', {'form': form})
4.Now that you have passed your Signup_form object in views layer, you can use django template tags to display them in your signup.html page. Here's how your signup.html could look like:
{% extends "base.html" %}
<link rel="stylesheet" href="{% static 'css/custom.css' %}">
{% block title %}Signup page{% endblock %}
{% block content %}
<div class="container" style="width:500px">
<h3 style="margin-top:100px">Sign Up</h3>
<hr>
<div class="login-form">
<form action="" method="post"> {% csrf_token %}
<div class="control-group span3" style="width:400px" >
{{ form.name.errors }}
{{ form.name }}
<i class="input-icon fui-user" for="login-name"></i>
</div>
<div class="control-group span3" style="width:400px" >
{{ form.email.errors }}
{{ form.email }}
<i class="input-icon fui-mail" for="login-name"></i>
</div>
<div class="control-group span3" style="width:400px">
{{ form.pass1.errors }}
{{ forms.pass2 }}
<i class="input-icon fui-lock" for="login-pass"></i>
</div>
<div class="control-group span3" style="width:400px">
{{ form.pass2.errors }}
{{ forms.pass2 }}
<i class="input-icon fui-lock" for="login-pass"></i>
</div>
<div style="text-align:center">
<input type="submit" class="btn btn-hg btn-primary btn-wide" value="Sign Up">
<!--<a class="login-link" href="#">Lost your password ?</a> -->
</div>
</form>
</div><!-- /login-form -->
</div> <!-- /container -->
{% endblock content %}
5.Since i have earlier moved your CSS styles(in point 2) into a 'form-control' class, now we will place it back by adding your styles in a external custom.css file. Create a custom.css file in the directory static/css/custom.css and add the following into it:
.form-control {
width:400px;
padding-bottom:15px;
margin-bottom:10px;
}
In your Views.py
from django.contrib.auth.models import User
def signup(request):
username = request.POST.get("name","")
password = request.POST.get("pass","")
login_pass = request.POST.get("login-pass","")
email = request.POST.get("email","")
if username != "" or password != "" or login_pass != "":
#do some validations
user = User.objects.create_user(username, email, password)
if user:
user.is_active = True
user.save()
return render(request, 'signup.html')
Above code will register a new user into system
If you would have use Django forms then all the validations will be done by Django.
Note: Please add name attribute to your HTML fields required for getting vaLues in request.POST. Also point your HTMl form action to "signup" view