In order to have a better overview on which page I'm loading which form, I would like to change the name with which it is accessed in the template. By default as far as I know it is set to 'form'. In the snipped below I'm trying to load the form with 'form_inv' but that doesn't work.
{% extends "dashboard/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Create Investment</legend>
{{ form_inv|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Create</button>
</div>
</form>
</div>
{% endblock content %}
The following is the Model I created and the respective view.
The Model:
class MoneyGroups(models.Model):
title = models.CharField(max_length=100)
size = models.IntegerField()
interest = models.FloatField()
The Django View:
class MoneyCreateView(LoginRequiredMixin, CreateView):
model = MoneyGroups
template_name = 'dashboard/scenario_form.html' # <app>/<model>_<viewtype>.html
context_object_name = 'investments'
fields = ['title', 'size', 'interest']
success_url = '/dashboard/'
def form_valid(self, form):
form.instance.author = self.request.user #add the author to the form before it is submitted
return super().form_valid(form)
What parameter do I have to change/add in my model or view in order to change the name with which I can access it in the template?
Thanks for your help!
Not sure why you would want to do this but add get_context_data method to your view like so:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context[‘form_inv’] = context[‘form’]
return context
Related
I want to add the functionality of adding comments in the same html page with post details starting from this class based view.
I also have left below the model and the html template that I want to use.
Please help me
The class based view that I want to use as a starting point :
class PostDetailView(DetailView):
model = Post
The model:
class Comments(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
content = models.TextField()
date_added = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.content
The html template:
<div id="comments">
<h3>{{ comments.total }}</h3>
<ol class="commentlist">
{% for comment in comments %}
<li class="depth-1">
<div class="avatar">
<img width="50" height="50" alt=""
src="{{ comment.user.profile.image.url }}"
class="avatar">
</div>
<div class="comment-content">
<div class="comment-info">
<cite>{{ comment.user }}</cite>
<div class="comment-meta">
<time datetime="2014-07-12T23:05"
class="comment-time">{{ comment.date_added|date:"F d, Y" }}</time>
</div>
</div>
<div class="comment-text">
<p>{{ comment.content }}</p>
</div>
</div>
</li>
{% endfor %}
</ol> <!-- /commentlist -->
<!-- respond -->
<div class="respond">
<h3>Leave a Comment</h3>
<!-- form -->
<form action="" method="POST">
{% csrf_token %}
<fieldset>
<div class="group">
{{ form|crispy }}
<button class="submit full-width" type="submit">Add Comment</button>
</div>
</fieldset>
</form> <!-- /contactForm -->
</div> <!-- /respond -->
</div> <!-- /comments -->
Override DetailView's get_context_data method to transfer comments through context. add this method in your class PostDetailView.
def get_context_data(self, **kwargs):
context = {}
if self.object:
context['object'] = self.object
context['comments']=Comments.objects.all() #modify this queryset according to how you want to display comments
context.update(kwargs)
return super().get_context_data(**context)
than in template you can include this piece of code
{% for comment in comments%}
<div>
{{comment}}
</div>
{% endfor %}
and to get comments, In forms.py
from django import forms
from .models import Comments
class CommentForm(forms.Form):
class Meta:
model = Comments
fields = [] #mention fields of comments u want to render in form
you have to extend FormView along with DetailView as DetailView dosent have post method to override.
So in views.py:
from .forms imoprt CommentForm
from django.views.generic.edit import FormView
class PostDetailView(DetailView, FormView):
model = Post
form_class = CommentForm
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
#do what you want with data
I suggest you go through the Methods of the classes to override them.FormView
im new to Django. Im creating a bidding site, where users should be able to visit a page to create a new listing (item that they are going to put up).The form that they are required to submit has a few common fields and when valid, the said form should be saved.
Problem is, my listingcreateview() is not doing that. I submit a correct form but it wont save, it just redirects to the same form page and No errors are shown.
This because the submitted form is validated as invalid every time. I know this because of the two functions i added inside listingcreateview(), the second one is called.
It was working properly before, dont know what changes messed it up. If i add in the admin interface information by hand, it is saved successfully.
views.py:
class ListingCreateView(CreateView):
model = Listing
fields = ['title', 'content', 'image', 'min_bid', 'categories']
def form_valid(self, form):
form.instance.seller = self.request.user
return super().form_valid(form)
def form_invalid(self, form):
return HttpResponseRedirect(reverse("index"))
models.py:
class User(AbstractUser):
pass
class Listing(models.Model):
id = models.IntegerField(primary_key=True)
title = models.CharField(max_length=100)
image = models.ImageField(blank=False, upload_to='media')
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
categories = models.CharField(max_length=25, choices = category)
seller = models.ForeignKey(User, on_delete=models.CASCADE) ##
min_bid = models.FloatField(blank=False)
image_thumbnail = ImageSpecField(source='image', processors=[ResizeToFill(300, 150)], format='JPEG', options={'quality':100})
def get_absolute_url(self):
return reverse('listing-detail', kwargs={'pk': self.pk})
listing_form.html:
{% extends "auctions/layout.html" %}
{% block body %}
<h2> Create Listing </h2>
{% if message %}
<div>{{ message }}</div>
{% endif %}
{% if messages %}
<div class="alert alert-warning" role="alert">
{{ messages }}
</div>
{% endif %}
<div class="container">
<form method="POST" action="">
{% csrf_token %}
<label class="label">{{ form.title.label }}</label>
<div class="input">{{ form.title }}</div>
<label class="label">{{ form.content.label }}</label>
<div class="input">{{ form.content }}</div>
<label class="label">{{ form.image.label }}</label>
<div class="input">{{ form.image }}</div>
<label class="label">Minimal bid</label>
<div class="input">{{ form.min_bid }}</div>
<label class="label">{{ form.categories.label }}</label>
<div class="input">{{ form.categories }}</div>
<input type="submit" value="Submit">
</form>
</div>
{% endblock %}
urls.py:
path("create-listing", login_required(ListingCreateView.as_view()), name="create-listing")
Your form is invalid because form is missing
enctype="multipart/form-data" which is needed for file uploads
I extend the django User model with a profile model. I want add update user's profile function. Because I make the num field a unique field, in my update view function, the update form's is_valid was always False. I also cannot update the photo png? Here is my code;
Models:
class Profile(models.model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
num =models.CharField('identity',max_length=254,unique=True)
photo = models.ImageField('image',upload_to = 'images/licences')
forms:
class ProfileForm(forms.ModelForm):
class Meta:
model= Profile
fields = ['num','photo']
views:
def modify_view(request):
user = request.user
if request.method=="POST":
form = ProfileForm(request.POST,request.FILES)
if form.is_valid()
user_profile = Profile.objects.get(user=user)
user_profile.image = form.clean_data['image']
user_profile.save()
else:
form = ProfileForm()
return render(request,"profile.html",{form:form})
template
{% extends 'account/home/index.html' %}
{% block content %}
<div class="row">
<div class="col-md-8 col-sm-8 col-8">
<form class="signup needs-validation" id="signup_form" method="post" enctype="multipart/form-data" >
{% csrf_token %}
{{form.as_p}}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<div class="form-group">
<button type="submit" class="col-sm-8 offset-sm-4 btn btn-success btn-block">update</button>
</div>
</form>
</div>
</div>
{% endblock %}
Since num field is unique and will not be generated again on updating the profile image, you can ignore request.POST and pass the instance argument to the ProfileForm class.
Example:
def modify_view(request):
user = request.user
if request.method=="POST":
user_profile = Profile.objects.get(user=user)
form = ProfileForm(files=request.FILES, instance=user_profile)
if form.is_valid():
user_profile.image = form.clean_data['image']
user_profile.save()
else:
form = ProfileForm()
return render(request,"profile.html",{form:form}
My custom CBV is working fine but When I open a page it displays nothing.
All I want is when a get() is called it displays a Blog Post and form underneath the post and when form is filled it calls the post() and save it in the database. but when I open a blog post it displays nothing.
before moving to Custom CBV I was using the (detailView) everything was fine.
class DetailView(View):
form_class = CommentForm
template_name = "blogs/details.html"
model = BLOG
def get(self, request, slug):
forms = self.form_class(None)
blogs = self.model
context = {'forms': forms, "blogs":blogs}
return render(request, self.template_name, context)
def post(self, request):
forms = self.form_class(request.POST)
if forms.is_valid():
user_comment = forms.save(commit=False)
Name = cleaned_data["Name"]
Email = cleaned_data["Name"]
comment = cleaned_data['comment']
user_comment.save()
blogs/details.html
{% extends "blogs/main.html" %}
{% block dyn_title %}{{blog.blog_title}}{% endblock dyn_title %}
{% block body %}
<h2>{{blog.blog_title}}</h3>
<p> {{blog.blog_body|safe}} </p>
<form action="" method="post">
{% csrf_token %}
{% include "blogs/form_template.html" %}
</form>
{% endblock body %}
<!-- form_template.html -->
{% for field in form %}
<label>{{field.label_tag}}</label>
<div class="">
{{field}}
</div>
{% endfor %}
I subscribed the code of my model, and after this i'm rendering this form django to put on a bootstrap form. I'm trying, without no sucess, put a datepicker in this form, but I dont found it in anywhere how to do this.
This is my model:
class Usuario(User):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
birthday = models.DateField("Birthday")
class Meta:
verbose_name = "Usuario"
This other code is about the form:
class FormUsuario(UserCreationForm):
class Meta:
model = Usuario
fields = ("username", "email", "birthday")
def __init__(self, *args, **kwargs):
super(FormUsuario, self).__init__(*args, **kwargs)
self.fields['username'].widget.attrs['placeholder'] = "Usuário"
self.fields['email'].widget.attrs['placeholder'] = "Email"
self.fields['password1'].widget.attrs['placeholder'] = "Senha"
self.fields['password2'].widget.attrs['placeholder'] = "Confirmar senha"
self.fields["birthday"].help_text = "mm/dd/aaaa"
self.fields['email'].required = True
When I used {% csrf_token %} {{ form|bootstrap_horizontal }} on template, is not show a datepicker.
{% load bootstrap %}
<form class="form-horizontal" method="POST" action="/cadastro/">
{% csrf_token %}
{{ form|bootstrap_horizontal }}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success btn-lg btn-block">Salvar</button>
</div>
</div>
</form>
{% endblock %}
How can I make up a datepicker on my bootstrap form?