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}
Related
I found out error message doesn't show up for some forms so I tried to do like this.
def add_entry(request):
if request.method != 'POST':
form = EntryForm(user=request.user)
else:
form = EntryForm(request.POST, user=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse_lazy('blog:list_entry'))
else:
print("error happened.")
context = {
'form': form,
}
return render(request, 'blog/add_entry.html', context)
and even when I tried to submit invalid data, it didn't output anything.
html
<form method="POST">
{% csrf_token %}
<div class="form-group">
{{ form.description.errors }}
<label>{{ form.description.label }}</label>
{{ form.description|add_class:'form-control' }}
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
models.py
class Entry(models.Model):
description = models.TextField(max_length=512)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
forms.py
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['description']
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super().__init__(*args, **kwargs)
def save(self):
entry = super().save(commit=False)
entry.user = self.user
entry.save()
return entry
When I submit valid data, the form does work. What am I wrong with this?
It sounds like your browser validation is preventing the form from being submitted when the description field is empty.
You can work around this by adding novalidate to the form. The browser will then allow you to submit a request with description="", and you should see the error from Django in the response.
<form method="POST" novalidate>
{% csrf_token %}
<div class="form-group">
{{ form.description.errors }}
<label>{{ form.description.label }}</label>
{{ form.description|add_class:'form-control' }}
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
Im new with Django and Im trying to include my own form
My forms.py
class MyOwnForm(forms.ModelForm):
class Meta:
model = Album
fields = ['username']
My views.py
def testing_Form(request):
if not request.user.is_authenticated:
return render(request, 'login.html')
else:
form = MyOwnForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
username = form.cleaned_data['username']
return render(request, 'form.html', {'form': form})
my form.html
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
and the last one form_template.html
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2" >{{ field.label_tag }}</label>
<div class="col-sm-10">{{ field }}</div>
</div>
{% endfor %}
When I open the Form Webpage, I get a empty entry field and the submit button. But when I click this button. The page is reloading and nothing more.
what do i have to do that i can work with the entered data?
But when I click this button. The page is reloading and nothing more.
Because of this, I'm assuming that you intend to show some information after the form is submitted. Here's a simple example that just displays an acknowledgement after the form is submitted.
{% if submitted %}
<div class="jumbotron contactainer">
<h1 class="display-4">Submitted</h1>
<hr class="my-4">
<p class="lead">{{ username }}'s album has been submitted</p>
</div>
{% else %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
{% endif %}
views.py
def testing_Form(request):
submit = False
if not request.user.is_authenticated:
return render(request, 'login.html')
else:
form = MyOwnForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.username = request.user
album.save()
submit = True
username = form.cleaned_data['username']
return render(request, 'form.html', {'username':username, 'submitted':submit})
else:
return render(request, 'form.html', {'form': form, 'submitted':submit})
You can do anything you wish with the username variable or add new variables, just remember to add them to the context dictionary if you wish to display them. The submit variable I've added is used in the template to determine what to show. Hope this helps :)
Not quite sure what you are exactly trying to achieve. However if you want to show the value of your previous submit on your screen for example as: Previous submitted username: <input username>, you can use the defined form in your template, including the values if there was a submit before.
{% if form.username.value %}
Previous submitted username: {{ form.username.value }}
{% endif %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{# ... all as it was ... #}
</form>
You can always add extra context to your template by assigning it to the context dictionary in the similar way you did with the {'form': form} as {'form': form, 'hello': "My hello string"} in your view.
In your template you could now use {{ hello }} as an variable.
Note that you are also using commit=False in your form to add more request data to the model after (user). Currently you left it in the unsaved state. To save the new form entry, you need to call album.save() after the modifications.
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
album.save() # now commit
The username = form.cleaned_data['username'] has been defined, but never been used. Which with the example above is no longer required.
You can fetch the album objects when the user is authenticated and pass them to the template to work with as context like:
(bad practice style, but just to give you an idea within the scope of your code)
if request.user.is_authenticated:
return render(request, 'login.html')
else:
form = AlbumForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
albums = Album.objects.all()
return render(request, 'formhandle/form.html', {'form': form, 'albums': albums})
Which you could show in your form template as:
{% if form.username.value %}
Previous submitted username: {{ form.username.value }}
{% endif %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{# ... all as it was ... #}
</form>
<ul>
{% for album in albums %}
<li>{{ album.user.username }}</li>
{% endfor %}
</ul>
trying to create a registration form, and I am facing an issue. so, below are my python pages:
form.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(ModelForm):
class Meta:
model = User
fields = ('username','password','email')
models.py
from django.db import models
#from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
class Registration(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
urls.py
urlpatterns = [
url(r'^register/$', views.SignUpFormView, name= 'register'),
]
test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form }}
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
<input type="submit" value="Submit" />
</form>
{% endblock %}
{% endblock %}
views.py
def SignUpFormView(request):
template_name = 'test.html'
try:
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
email = form.cleaned_data.get('email')
return render(request, template_name, {'form':form})
except ValueError:
print("Oops! That was not a valid entry, try again...")
else:
SignUpForm()
return render(request, 'user_info/about.html')
The issue is, my "SignUpFormView" function in views.py is not entering the "if" statement, its directly going to "else". I seem to be lost here.
I have 'about.html'. I do not see any error as well. Which I find very weird. Please help.
Note: I am using Django's default in-built "User" model, and I do not wish to create any custom model.
Modified views.py
def SignUpFormView(request):
user_form = 'SignUpForm'
template_name = 'test.html'
if request.method == 'POST':
form = user_form(request.POST)
if form.is_valid():
form.save()
#username = form.cleaned_data.get('username')
#password = form.cleaned_data.get('password')
#email = form.cleaned_data.get('email')
#user.save()
return render(request, template_name, {'form':form})
else:
SignUpForm()
return render(request, 'user_info/about.html')
Modified forms.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(forms.ModelForm):
#password = forms.Charfield(widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username','password','email')
modified test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
{% for error in form.errors %}
{{ form.errors | default_errors }}
{% endfor %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{% for field in form %}
<p>
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit" value="Submit">sign up </button>
</form>
{% endblock %}
{% endblock %}
How to set value of who and image in template?
class CommentForm(ModelForm):
who = forms.CharField(widget=forms.HiddenInput())
image = forms.ImageField(widget=forms.HiddenInput())
class Meta:
model = Comments
fields = ['who', 'image', 'content']
It doesn't work (raw text):
<form method='POST' action=''>
{% csrf_token %}
{% render_field comment_form.content class="form-control form-control-sm" placeholder='Comment..' %}
{% render_field comment_form.who class="form-control form-control-sm" value='{{ request.user.profile.pk }}' %}
{% render_field comment_form.image class="form-control form-control-sm" value='{{ image.pk }}' %}
<input class="btn btn-primary btn-sm" type="submit" value="Add comment">
</form>
My views.py:
class ProfileView(DetailView):
comment_form = CommentForm()
queryset = Profile.objects.all()
context_object_name = 'me'
template_name = 'profile.html'
def get_context_data(self, **kwargs):
context = super(ProfileView, self).get_context_data(**kwargs)
context['comment_form'] = self.comment_form
return context
You need to set the initial property of the form field, after you've instantiated the form in your view. Like so:
class ProfileView(DetailView):
comment_form = CommentForm()
queryset = Profile.objects.all()
context_object_name = 'me'
template_name = 'profile.html'
def get_context_data(self, **kwargs):
context = super(ProfileView, self).get_context_data(**kwargs)
context['comment_form'] = self.comment_form
# This sets the initial value for the field:
context['comment_form'].fields['who'].initial = self.request.user.profile.pk
return context
It is an old question, but I will put my answers to try to help those in need.
You can set initial value dynamical in your view
link in Django documentation: https://docs.djangoproject.com/en/3.1/ref/forms/api/#dynamic-initial-values
Use initial to declare the initial value of form fields at runtime. For example, you might want to fill in a username field with the username of the current session.
To accomplish this, use the initial argument to a Form. This argument, if given, should be a dictionary mapping field names to initial values. Only include the fields for which you’re specifying an initial value; it’s not necessary to include every field in your form
eg
comment_form = CommentForm(initial={'who ': request.user.profile.pk})
You can do some thing like this. This is a pure HTML approach.
Inside the from add the
<input type="hidden" name="content" value="{{value}}">
Put the field inside the name attribute and set the value to anything you want inside the value attribute.
<form method='POST' action=''>
{% csrf_token %}
{% render_field comment_form.content class="form-control form-control-sm" placeholder='Comment..' %}
{% render_field comment_form.who class="form-control form-control-sm" value='{{ comment_form.who }}' %}
{% render_field comment_form.image class="form-control form-control-sm" value='{{ comment_form.image }}' %}
<input class="btn btn-primary btn-sm" type="submit" value="Add comment">
</form>
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?