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?
Related
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'm trying to create reservation create view that allows to break down the reservation process into 3 stages for handling all the database queries and displaying relevant choices accordingly to linkage between models (Personnel Profile has many to many key on Service)
1st stage - allows user to select service
2nd stage - displays available staff members (PersonnelProfile) who are handling this service
3rd stage - displays all the free dates / times based on staff member schedule / existing reservations, POST creates the reservation
I got stuck at the 2nd stage as my form doesn't validate. I would appreciate any advise how to overcome this issue or how to handle the idea differently. Sorry for the long post :)
UPDATE
My goal is following:
1. User selects a service
2. Backend checks which personnel profiles are offering this service and returns from to select relevant user
3. Based on selected user backend checks availability (Schedule) of user, his existing reservations and returns form for date / hour selection
4. Reservation is created after user submits from with selected hour and time
I tried to do it with additional forms to split the process in stages, as I have no idea (unfortunately I'm still a newbie) how to handle such behaviour with one form and if it's possible or not. I would appreciate any tips / guidance on how to handle this.
Reservation
class Reservation(models.Model):
user = models.ForeignKey(PersonnelProfile, on_delete=models.PROTECT)
client = models.ForeignKey(ClientProfile, on_delete=models.PROTECT)
service = models.ForeignKey(Service, on_delete=models.PROTECT)
date = models.DateField()
start_time = models.TimeField()
Service
class Service(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
price = models.IntegerField()
duration = models.IntegerField()
def __str__(self):
return self.name
PersonnelProfile
class PersonnelProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
birth_date = models.DateField(default=None, null=True)
address = models.CharField(max_length=200)
services = models.ManyToManyField(Service)
image = models.ImageField(default='profile_pics/default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.first_name} {self.user.last_name}'
Schedule Model
class Schedule(models.Model):
user = models.OneToOneField(PersonnelProfile, on_delete=models.CASCADE)
availability_days = models.ManyToManyField(WorkDay)
start_hour = models.TimeField()
end_hour = models.TimeField()
def __str__(self):
return f'Schedule of {self.user.user.first_name} {self.user.user.last_name}'
WorkDay Model
class WorkDay(models.Model):
day_choices = [(str(i), calendar.day_name[i]) for i in range(7)]
name = models.CharField(max_length=9, choices=day_choices, default='1', unique=True)
def __str__(self):
return self.get_name_display()
Reservation CreateView
class ReservationCreate(LoginRequiredMixin, UserPassesTestMixin, ModelFormWidgetMixin, CreateView):
model = Reservation
success_url = '/reservations'
#staticmethod
def get(request):
form = ServiceSelection()
return render(request, 'reservations/reservation_service_selection.html', context={'form': form})
#staticmethod
def post(request):
if 'service_selection' in request.POST:
form = ServiceSelection(request.POST)
if form.is_valid():
service = form.cleaned_data['select_service']
available_personnel = PersonnelProfile.objects.filter(services=service)
personnel_names = [prs.user for prs in available_personnel]
form = PersonSelection(personnel_names)
context = {
'form': form,
'service': service
}
"""
Selected service data should be saved for the 3rd stage
"""
return render(request, 'reservations/reservation_person_selection.html', context)
return HttpResponse('Service incorrect', 404)
if 'person_selection' in request.POST:
form = PersonSelection(request.POST)
if form.is_valid():
"""
Check the schedule and existing reservations
Return last form with available dates and times for service selected in stage 1
and staff member selected in 3rd stage.
3rd stage will create Reservation with all the selected details in all 3 stages
"""
return HttpResponse('Good choice', 200) #response just for tests
return render(request, 'reservations/reservation_person_selection.html', {'form': form})
def test_func(self):
if self.request.user.is_staff:
return True
return False
Forms
class ServiceSelection(forms.ModelForm):
select_service = forms.ModelChoiceField(
queryset=Service.objects.all(),
widget=forms.Select(),
empty_label='Please select a service',
to_field_name='price'
)
class Meta:
model = Service
fields = ('select_service',)
class PersonSelection(forms.ModelForm):
def __init__(self, personnel_names, *args, **kwargs):
super(PersonSelection, self).__init__(*args, **kwargs)
self.fields['user'] = forms.ChoiceField(
choices=tuple([(name, name) for name in personnel_names]),
label='Select a person'
)
class Meta:
model = PersonnelProfile
fields = 'user',
Templates :
reservation_service_selection
{% extends 'website/home.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="/media/profile_pics/default.jpg">
<div class="media-body">
<h2 class="account-heading">Select a service</h2>
</div>
</div>
</div>
<div class="content-section">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit" name="service_selection">Update</button>
<input type="button" value="Go back" class="btn btn-outline-info" onclick="history.back()">
</div>
</form>
</div>
{% endblock %}
reservation_person_selection
{% extends 'website/home.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="/media/profile_pics/default.jpg">
<div class="media-body">
<h2 class="account-heading">Select a person</h2>
</div>
</div>
</div>
<div class="content-section">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
<fieldset disabled>
<fieldset class="form-group">
<div class="form-group">
<label for="disabledSelect">Select a service*</label>
<select id="disabledSelect" class="form-control">
<option>{{ service }}</option>
</select>
</div>
</fieldset>
</fieldset>
{{ person_form|crispy }}
<div class="form-group">
<button class="btn btn-outline-info" type="submit" name="person_selection">Update</button>
<input type="button" value="Go back" class="btn btn-outline-info" onclick="history.back()">
</div>
</form>
</div>
I am trying to go to the author profile if i press on his name. This is my HTML which do these:
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
</div>
</div>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Profile Info</legend>
<p class="text-secondary"><h3>Contact Me Here: </h3>{{ user.email }}</p>
</fieldset>
</form>
</div>
{% endblock content %}
In my views.py i have this:
def author_profile(request):
user = Post.author
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileUpdateForm(instance=request.user.profile)
context = {
'u_form': u_form,
'p_form': p_form
}
return render(request, 'blog/author_profile.html', context)
Where UserUpdateForm and ProfileUpdateForm from the forms.py have this code:
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email']
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image']
Class for the Post:
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
If i press on the name it is getting me to the user profile, I tried to work with Post.author but didn't worked.
It's my first time with django.
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}
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>