django how to catch a variable of a form in template - python

I want to use feedback forms in my app. And I have FeedBack model and FeedBackForm form.
models.py:
class Feedback(models.Model):
name = models.CharField(max_length=150, blank=True)
email = models.EmailField(blank=True)
comment = RichTextField()
forms.py:
class FeedBackForm(forms.ModelForm):
class Meta:
model = Feedback
fields = ('name', 'email', 'comment')
I used FeedBackForm in my views,py file
views.py
def home(request):
if request.method == 'POST':
feedback_form = FeedBackForm(data=request.POST)
if feedback_form.is_valid():
feedback_form.save()
else:
feedback_form = FeedBackForm()
return render(request, 'home.html', {'feedback_form': feedback_form})
Now my question is: how can I use my variables in template? Instead of this 3 input tags. (Is there another easier way other than
{{ feedbackform.as_p }}
and
{% csrf_token %}
to call my form variables "name", "email" and "comment" as input). Thanks in anvance
<form action="." method="post">
<input type="text" name="name">
<input type="email" name="email">
<textarea name="comment"></textarea>
</form>

If I get your question right, you want to call form.name, form.email and form.comment in template? See more at https://docs.djangoproject.com/ja/1.9/topics/forms/#rendering-fields-manually

Related

Django - Query To Check if Item In Many to Many Relationship Field

I have a User and a Deal model as shown below. The User model has a 'favorites' field which is a many to many relationship with the Deal model.
I'm trying to allow a user to save a Deal to their Favorites. I have tested both the favorite and remove_favorite views and both are doing exactly what they are supposed to do.
Here's My Issue -- The conditional statement on my deal_detail.html page which checks to see if the current deal on the page is a favorite of the logged in user doesn't seem to be working.
{% if deal_detail in user.favorites %}
I'm just having a hard time wrapping my head around how to check this.
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, error_messages={'unique':"This email has already been registered."})
username = models.CharField(max_length=40, default='')
first_name = models.CharField(max_length=40, default='', blank=True)
last_name = models.CharField(max_length=40, default='', blank=True)
date_joined = models.DateTimeField(default=timezone.now)
favorites = models.ManyToManyField(Deal, related_name='favorited_by', null=True, blank=True)
class Deal(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=140, unique=True)
description = models.TextField(default='')
My corresponding views look like this:
def deal_by_detail(request, slug):
deal_detail = Deal.objects.get(slug=slug)
user = request.user
return render(request, 'deals/deal_detail.html', {'deal_detail': deal_detail, 'user': user})
#login_required(login_url='/accounts/sign_in/')
def favorite(request, pk):
if request.method == 'POST':
favorite = Deal.objects.get(pk=pk)
user = request.user
user.favorites.add(favorite)
messages.add_message(request, messages.INFO, 'Deal Favorited.')
return redirect('home')
#login_required(login_url='/accounts/sign_in/')
def remove_favorite(request, pk):
if request.method == 'POST':
favorite = Deal.objects.get(pk=pk)
user = request.user
user.favorites.remove(favorite)
messages.add_message(request, messages.INFO, 'Deal Removed.')
return redirect('home')
My form deal_detail.html looks like this:
{% if deal_detail in user.favorites %}
<form id="favorite{{deal_detail.id}}" method="POST" action="{% url 'deals:favorite' deal_detail.id %}">
{% csrf_token %}
<input type="hidden" name="supporttype" />
<input type="submit" value="Add Deal to Favorites" />
</form>
{% else %}
<form id="favorite{{deal_detail.id}}" method="POST" action="{% url 'deals:remove_favorite' deal_detail.id %}">
{% csrf_token %}
<input type="hidden" name="supporttype" />
<input type="submit" value="Remove Deal From Favorites" />
</form>
{% endif %}
I believe you are just missing the .all after the manytomany field. Then it should be able to run the check and function as you intended
{% if deal_detail in user.favorites.all %}

Django error when trying to display the sign up form

So I have this form which extends the User and I just want to allow the student to create and account and be able to select the courses from the course list.But when I try, I get the error:
__init__() takes 1 positional argument but 2 were given
I can't find any solution to this yet. I need some advice.
These are my files:
{% block body %}
<div class="row">
<div class="col-md-8 col-sm-10 col-12">
<h2>Sign up as a {{ user_type }}</h2>
<form method="post" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}">
{{ form }}
<button type="submit" class="btn btn-success">Sign up</button>
</form>
</div>
</div>
{% endblock %}
class User(AbstractUser):
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
path('signup/', views.StudentSignUpView, name='signup')
class StudentSignUpForm(UserCreationForm):
attended_courses = forms.ModelMultipleChoiceField(
queryset=Course.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=True
)
class Meta(UserCreationForm.Meta):
model = User
#transaction.atomic
def save(self):
user = super().save(commit=False)
user.is_student = True
user.save()
student = Student.objects.create(user=user)
student.attended_courses.add(*self.cleaned_data.get('attended_courses'))
return user
class StudentSignUpView(CreateView):
model = User
form_class = StudentSignUpForm
template_name = 'signup_form.html'
def get_context_data(self, **kwargs):
kwargs['user_type'] = 'student'
return super().get_context_data(**kwargs)
def form_valid(self, form):
user = form.save()
login(self.request, user)
return redirect('index')
Class-based views need to be referenced in urls.py via their as_view method.
path('signup/', views.StudentSignUpView.as_view(), name='signup')

Rendering django model validation error in template

I am building a web application on django. As part of this, I have created one html form like following:
<form method="post" action="/voting/add_state/">{% csrf_token %}
State name:<br>
<input type="text" name="state_name"><br>
<input type="submit" value="Submit">
</form>
In models.py I have added unique constraint validation on name like following:
class State(models.Model):
name = models.CharField(max_length=200, unique=True)
vote_counted = models.BooleanField(default=False)
So for duplicate name, it throws a unique constraint error which I would like to capture in the template. Can anyone please give any suggestion.
Create a form based on your model
#forms.py
from django import forms
from .models import State
class StateForm(forms.ModelForm):
class Meta:
model = State
fields = ('name',)
now use this form on your views
#views.py
from django.views.generic import FormView
from .forms import StateForm
class MyView(FormView):
template_name = 'template.html'
form_class = StateForm
success_url = '/my-url-to-redirect-after-submit/'
template.html
<form method="post">
{% csrf_token %}
Name
{{ form.name }}
{{ form.name.errors }}
<input type="submit" value="Create">
</form>
Django has Form processing built in. Django has "Model Forms", which automatically render the form for your model. If you pass it through the view and reference it in the context it will automatically generate the html for you, but if you would like more control over what is rendered in the template then you can reference the form attributes that Django Model Form produces.
I strongly suggest working within the framework Django provides to you for building forms; it provides a lot of boilerplate code for building, validating and abstracting forms and is especially competent for simple forms like these.
Here is an example:
models.py
class State(models.Model):
name = models.CharField(max_length=200, unique=True)
vote_counted = models.BooleanField(default=False)
forms.py
class StateForm(forms.ModelForm):
model = State
fields = (name,)
views.py
from django.views.generic.edit import FormView
class StateForm(FormView):
template_name = 'state_form.html'
form_class = StateForm
success_url = '/thanks/'
state_form.html (example of auto generated form)
{{ form }}
state_form.html (example of custom form)
<form action="/" method="post">
{% csrf_token %}
{{ form.errors }}
{% for field in form %}
<input type="{{ field.type }}" name='{{ field.name }}' class="submit" value="{{ field.value}}">
{% endfor %}
<input type="submit" name='submit" value="Submit">
</form>
References:
Django Forms:
https://docs.djangoproject.com/en/1.9/topics/forms/
Django Model Forms: https://docs.djangoproject.com/en/1.9/topics/forms/modelforms/
Django Generic Views:
https://docs.djangoproject.com/en/1.9/ref/class-based-views/generic-editing/#django.views.generic.edit.FormView
You could create a form for State model and create the validator, so if the user try with a duplicate name, the form raise a message something like this:
models.py
class State(models.Model):
name = models.CharField(max_length=200, unique=True)
vote_counted = models.BooleanField(default=False)
forms.py
def unique_name(value):
exist = State.objects.filter(name=value)
if exist:
raise ValidationError(u"A state with the name %s already exist" % value)
class StateForm(forms.Form):
name = forms.CharField(label=('Name:'), validators=[unique_name])
Then you just need to render the StateForm in the template.

Updating user in django

In my application, I used email and password for user authentication, which works fine. However, I want to offer the user the option of adding other information to their account like first names, last names, and dates of birth.
I have a change form in myapp.forms.py
class MyChangeForm(forms.ModelForm):
"""
Form for editing an account.
"""
first_name = forms.CharField(widget=forms.TextInput, label="First name")
last_name = forms.CharField(widget=forms.TextInput, label="Last name")
date_of_birth = forms.DateField(widget=forms.DateField, label="Date of birth")
class Meta:
model = MyUser
fields = ['first_name', 'last_name', 'date_of_birth']
def save(self, commit=True):
user = super(MyChangeForm, self).save(commit=False)
if commit:
user.save()
return user
in my views.py, I have the following method for updating
#login_required(login_url='/')
def update_user(request):
if request.method == 'POST':
form = MyChangeForm(request.POST, instance=request.user)
if form.is_valid():
user = form.save(commit=False)
user.save()
return HttpResponseRedirect('/')
else:
form = MyChangeForm(instance=request.user)
return render_to_response('update_user.html', context_instance=RequestContext(request))
and my update_user.html is as follows
{% extends 'user_base.html' %}
{% block content %}
<div class="col-sm-3 col-sm-offset-5">
<h1> Update User</h1>
<form method='POST' action='/update_user/'> {% csrf_token %}
<ul>
{{ form.as_table }}
</ul>
<input type='Submit' class='btn btn-primary btn-block'>
</form>
</div>
{% endblock %}
However, when I serve the file I see this:
As seen here, there's no way to enter my fields!
How can I fix this? It's probably easy, but I'm getting tunnel vision.
erip
Add form to the context, for example like this:
render('update_user.html', {'form': form})

How to save Django ModelForm data?

I have created form using ModelForm but its not saving data into database.
views.py
def answer(request):
if request.method == 'POST':
form = AnswerForm(request.POST)
if form.is_valid():
form.save()
else:
form = AnswerForm()
return render_to_response('quiz/index.html', {'form': form, })
template
<form action="." method="post">
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
model
class Answer(models.Model):
answer = models.TextField()
class AnswerForm(ModelForm):
class Meta:
model = Answer
Where i was wrong ? :/
You forgot to handle the case where the form isn't valid.

Categories