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.
Related
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 }}">
I'm trying to find a solution for 2 days now... can't figure out why login does not work for me once I have changed any user details.
Normal flow works fine for me: user registers, logs in and out without a problem. But I thought it would be good to have profile change option where a user can change username, password or email. I did implement this, but after a user changes anything (even email), the login form does not admit him.
Here is my views.py:
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, PasswordChangeForm
from .forms import ContactForm, CreateUserForm, EditUserForm
class ProfileView(UpdateView):
template_name = 'boat_app/edit_profile.html'
form_class = UserChangeForm
success_url = reverse_lazy('anchored')
def get_object(self):
return self.request.user
class LoginView(TemplateView):
template_name = 'boat_app/login.html'
success_url = reverse_lazy('category_home')
def post(self, request):
print(request)
user = authenticate(request, username=request.POST.get('username'), password=request.POST.get('password'))
if user is not None:
print('user not none')
login(request, user)
return HttpResponseRedirect(reverse('anchored'))
else:
print('user none')
messages.info(request, 'Username OR password is incorrect')
return HttpResponseRedirect(reverse('login'))
And forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class EditUserForm(forms.ModelForm):
class Meta:
model = User
fields = ('username', 'email')
After changing a user I see this change in admin interface, so it does work. But I can't see a reason why the system does not see this relation. Any way to debug what exactly is going on there?
UPDATE
I've tried changing the user via admin backend - all works fine. I've also tried using {{ form.as_p }} instead of my custom template for ProfileView - and this also worked! So apparently there is something fishy going on with my html template which ruins the update view and does nont allow to collect data for future login.
Here is my 'boat_app/edit_profile.html'
{% block body_block %}
<div class="row align-items-center vh-100">
<div class="col-lg-4 d-none d-md-block">
</div>
<div class="col-lg-4 d-flex align-items-center">
<div class="container p-3 text-center bg-light">
<div class="my-3">
<h1>Change your details</h1>
<p>Did something change?</p>
</div>
<form method="post">
{% csrf_token %}
<div class="form-group row px-3">
<label for="{{ form.username.id_for_label }}">{{form.username.label}}</label>
{% render_field form.username class="form-control" %}
</div>
<div class="form-group row px-3">
{{ form.email.errors }}
<label for="{{ form.email.id_for_label }}">{{form.email.label}}</label>
{% render_field form.email class="form-control" %}
</div>
<div class="form-group row px-3">
{{ form.password.errors }}
<label for="{{ form.date_joined.id_for_label }}">{{form.date_joined.label}}</label>
{% render_field form.date_joined class="form-control" %}
</div>
<div class="form-group row text-left px-3">
<p>If you need to change password, click here.</p>
</div>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
</div>
</div>
<div class="col-lg-4 d-none d-md-block">
</div>
</div>
{% endblock %}
I am brand new to Django.
I made a register form.
One time out of two, when i try to register a new user i have an exception "auth_user.username"
it seems there is no rule, it can works many times in a row and with new user registration i have the error!
Here is my form.py
from django.contrib.auth.forms import UserCreationForm,AuthenticationForm
from django.contrib.auth.models import User
from bootstrap_modal_forms.mixins import PopRequestMixin, CreateUpdateAjaxMixin
from django import forms
class CustomUserCreationForm(PopRequestMixin, CreateUpdateAjaxMixin,
UserCreationForm):
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
def clean_email(self):
if User.objects.filter(email=self.cleaned_data['email']).exists():
raise forms.ValidationError("the given email is already registered")
return self.cleaned_data['email']
'''
views.py
enter code here
from django.urls import reverse_lazy
from bootstrap_modal_forms.generic import BSModalCreateView,BSModalLoginView
from .forms import CustomUserCreationForm,CustomAuthenticationForm
class SignUpView(BSModalCreateView):
form_class = CustomUserCreationForm
template_name = 'signup.html'
success_message = 'Success: Sign up succeeded. You can now Log in.'
success_url = reverse_lazy('index')
signup.html
enter code here
{% load widget_tweaks %}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-
q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
body data-spy="scroll" data-target=".site-navbar-target" data-offset="300">
<form method="post" action="">
{% csrf_token %}
<div class="modal-header">
<h3 class="modal-title">Register</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="{% if form.non_field_errors %}invalid{% endif %} mb-2">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</div>
{% for field in form %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{% render_field field class="form-control" placeholder=field.label %}
<div class="{% if field.errors %} invalid{% endif %}">
{% for error in field.errors %}
<p class="help-block" style="color:red">{{ error }}</p>
{% endfor %}
</div>
</div>
{% endfor %}
Register
THANK YOU
I remember two ways we can accomplish that:
Override the User model's save method and only try to save if the object does not exist:
def save(self, *args, **kwargs):
if not User.objects.filter(name=self.name).first():
super(User, self).__init__(*args, **kwargs)
Create your custom model and inherit from User, and drop the unique constraint:
class CustomUser(User):
username = models.CharField(_("User name"), max_length=30, blank=False)
This way you have more control of your validations.
I'm using django-crispy-forms, a third party library, in a Django project, I would like to customize a form to get the errors at top of the form, but I can't.
This is a snippet of the code:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="col-sm-6">
<h1>Add New Task</h1>
<form action="" method="post">{% csrf_token %}
<div class="row">
<div class="col-sm-12">{{ form|as_crispy_errors:"bootstrap3" }}</div>
<div class="col-sm-10">{{ form.project|as_crispy_field }}</div>
<div class="col-sm-2" id="add-new">
Add new
</div>
</div>
<div class="row">
<div class="col-sm-12">{{ form.title|as_crispy_field }}</div>
</div>
<button class="btn btn-primary" type="submit">Add</button>
</form>
</div>
{% endblock content %}
The view:
def new_task(request):
form = NewTaskForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
return redirect('/pomodoro/home')
return render(request, 'pomodoro/new-task.html', {
'form': form,
})
This is my form:
from django import forms
from .models import Task
class NewTaskForm(forms.ModelForm):
class Meta:
model = Task
fields = ['project', 'title',]
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