So I have a base.html file where all the components that are common in all the other templates are present. I'm trying to implement Newsletter form functionality in my django project. This form should be displayed on all the pages(in the top navbar).
But the problem here is that this form only shows up on base.html and not the other template pages which extend this file.
base.html
{% load static %}
<html lang="en">
<body>
<div id="overlay">
<div class="overlay-body form-group">
<h2>Subscribe to our newsletter</h2>
<form method="post">
{% csrf_token %}
{{form}}
<button type="reset" onclick="off()">Cancel</button>
<button type="submit" value="submit">Submit</button>
</form>
</div>
</div>
<div class="container">
<header>
<div>
<div class="col-4 "><a id="blog-side" onclick="on()">Subscribe</a></div>
<div class="col-4 ">
<img src="{% static 'img/logo.png' %}" alt="Logo">
Blog
</div>
<div class="col-4 ">About</div>
</div>
</header>
{% block content %}
{% endblock content %}
</div>
</body>
</html>
Here's the Newsletter form from models.py
class Newsletter(models.Model):
email = models.EmailField()
entered_on = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
def __str__(self):
return self.email
forms.py
class NewsletterForm(forms.ModelForm):
class Meta:
model = Newsletter
fields = ('email', )
Any idea as to how to setup this form in the other templates?
The thing here is that you will need to make sure you send in the form in every single view you create. Can I see your views.py file please?
Related
I have made filters using django-filters. As a result I get a dropdown menu. Is it possible to add an autocomplete/search field to this dropdown?
I have already tried to add the Select2Widget widget as indicated in another post, but the only thing that changes is that it adds an empty field before the dotted line. But it won't let me write anything.
Maybe something is missing in the template???
Stackoverflow don't let me add images yet so I share the code I have.
filters.py
import django_filters
from django_select2.forms import Select2Widget
from .models import Consumo, Cliente
AÑO_CHOICES = (('2021', '2021'), ('2022', '2022'),)
class ConsumoFilter(django_filters.FilterSet):
año = django_filters.ChoiceFilter(choices=AÑO_CHOICES, label='Año', widget=Select2Widget(attrs={'style':'width: 20ch', 'class':'form-select form-select-sm'}))
name = django_filters.ModelChoiceFilter(queryset=Cliente.objects.all(), label='Clientes', widget=Select2Widget(attrs={'style':'width: 85ch','class': 'form-select form-select-sm'}))
class Meta:
model = Consumo
fields = ['name', 'año']
template
{% extends 'clientes/base.html' %}
{% load static %}
{% block title %}Title{% endblock %}
{% block head %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js" integrity="sha512-2ImtlRlf2VVmiGZsjm9bEyhjGW4dU7B6TNwh/hx/iSByxNENtj3WVE6o/9Lj4TJeVXPi4bnOIMXFIJJAeufa0A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
{% endblock %}
{% block content %}
<div class="card" style="margin-top: 20px; margin-bottom: 20px;">
<div class="card-body">
<h4 class="card-title">Consumos</h4>
<h6 class="card-subtitle mb-2 text-muted">Consumos por cliente</h6>
<hr>
<div class="container">
<div class="row">
<div class="col-lg-12">
<form method="get">
{{ consumo_filter.form }}
<br>
<button type="submit" class="btn btn-sm btn-primary">Buscar</button>
</form>
<hr>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block javascript %}
{% endblock %}
Ok, I found out.
You need to add a id="" attribute to attrs=
name = django_filters.ModelChoiceFilter(queryset=Cliente.objects.all(), label='Clientes', widget=Select2Widget(attrs={'style':'width: 85ch', 'id':'name', 'class': 'form-select'}))
Then in your template you call it with the Select2 JS code:
{% block javascript %}
<script>
$(document).ready(function() {
$('#name').select2();
});
</script>
{% endblock %}
I am new to django and I am working on student login for examination portal. I am basically passing two forms in my view. One form is for getting the user details and second is for storing details of student.
I have used django widget tweak package to load the fields of my forms. My user gets created but at the same time I still get the error- UNIQUE constraint failed: auth_user.username.
Here's my model.py
class StudentInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
mobile = models.IntegerField(max_length=20, blank=True)
branch = models.CharField(max_length=50, blank=True)
forms.py
class StudentForm(forms.ModelForm)
class Meta():
model = User
fields = ['username', 'email', 'password']
widgets = {
'password': forms.PasswordInput()
}
class StudentInfoForm(forms.ModelForm):
class Meta():
model = StudentInfo
fields = ['mobile','branch']
views.py
def register(request):
userForm= forms.StudentForm()
studentForm=forms.StudentInfoForm()
mydict={'userForm':userForm,'studentForm':studentForm}
if request.method=='POST':
userForm=forms.StudentForm(request.POST)
studentForm=forms.StudentInfoForm(request.POST)
if userForm.is_valid() and studentForm.is_valid():
user=userForm.save()
user.is_active = True
user.set_password(user.password)
messages.success(request,"Student User created Succesfully.")
student=studentForm.save(commit=False)
student.user=user
student.save()
my_student_group = Group.objects.get_or_create(name='STUDENT')
my_student_group[0].user_set.add(user)
return redirect('login')
return render(request,'student_signup.html',context=mydict)
html file
{% load widget_tweaks %}
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>Student Signup</title>
</head>
<body>
<h1 style="text-align: center; margin-top: 5px;">Student Signup</h1>
<div class="container mt-5" style="width: 50%;">
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="username" class="form-label">Username</label>
{
{% render_field userForm.username type="text" class="form-control" %}
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
{% render_field userForm.password type="password" class="form-control" %}
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
{% render_field userForm.email type="email" class="form-control" %}
</div>
<div class="mb-3">
<label for="branch" class="form-label">Branch</label>
{% render_field studentForm.branch type="text" class="form-control" %}
</div>
<div class="mb-3">
<label for="mobile" class="form-label">Mobile</label>
{% render_field studentForm.mobile type="number" class="form-control" %}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
I searched on the internet and found that this happens when we save the form twice but I don't think I am doing so.I am calling the save method only once.
I think that this occurs because your user instance is bound to the form and not a model instance itself which you then assign to your student instance
Try it like so:
def register(request):
userForm= forms.StudentForm()
studentForm=forms.StudentInfoForm()
mydict={'userForm':userForm,'studentForm':studentForm}
if request.method=='POST':
userForm=forms.StudentForm(request.POST)
studentForm=forms.StudentInfoForm(request.POST)
if userForm.is_valid() and studentForm.is_valid():
user=userForm.save()
user.is_active = True
user.set_password(user.password)
messages.success(request,"Student User created Succesfully.")
student=studentForm.save(commit=False)
student.user=user.instance # user is bound to the form instance not the model instance
student.save()
my_student_group = Group.objects.get_or_create(name='STUDENT')
my_student_group[0].user_set.add(user)
return redirect('login')
return render(request,'student_signup.html',context=mydict)
I think I have a pretty basic UpdateView but the object is not saved when I submit the form. The success_url is never called. When I click the Update button, the form refreshes and I stay on the same page. I am able to update the object via admin, so I believe the model is working fine. I am not getting any errors.
urls
path('classroomdetail/<uuid:classroom_id>/',
views.classroomdetail, name='classroomdetail'),
path('classedit/<uuid:pk>/', views.ClassroomUpdateView.as_view(), name='classupdate'),
Model
class Classroom(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
classroom_name = models.CharField(max_length=20)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
students = models.ManyToManyField(Student)
class Meta:
constraints = [models.UniqueConstraint(
fields=['user', 'classroom_name'], name="unique-user-classroom")]
def __str__(self):
return self.classroom_name
views
class ClassroomUpdateView(UpdateView):
model = Classroom
fields = ['classroom_name']
template_name_suffix = '_update'
success_url = reverse_lazy('gradebook:classroom')
template
{% extends 'base.html' %} {% load static %} {% block content %}
{% load crispy_forms_tags %}
<div class="container">
<div class="row">
<div class="col">
<h3>This Classroom belongs to {{ classroom.course }}</h3>
</div>
</div>
<div class="row">
<div class="col-md-3">
<form class="form-group">
{% csrf_token %}{{ form|crispy }}
<input type="submit" class="btn btn-primary mt-2 mb-2" value="Update">
</form>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="ps-2">Cancel
</div>
</div>
</div>
{% endblock content %}
I was missing method="post" in my template. Correct line:
<form method="post" class="form-group">
When I submit my form, it doesn't post the form data and just reloads the form.
It was working beforehand but I'm not sure what I've changed that doesn't make it work anymore. Posting the data through the admin still works fine.
The only 'error' message I can see is in the terminal:
which can be seen here
It sends a get request instead of a post request as well. I've also tested it with removing the JS and bootstrap CDNs but the issue is still the same.
My code is below:
Here is my views.py
def create(request):
if request.method == 'POST':
form = EventCreateForm(request.POST, request.FILES)
if form.is_valid():.
instance = form.save(commit=False)
instance.author = request.user
instance.save()
instance.save_m2m()
return redirect('event:home')
else:
form = EventCreateForm()
return render(request, 'event/create.html', {'form': form})
create.html
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
{{ form.media }}
<div class="container-fluid">
<div class="col-md-4">
<div class="page-header">
<p> Create an event!</p>
</div>
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ form | crispy}}
<button type="submit">Submit</button>
<br>
<br>
</form>
</div>
</div>
{% endblock %}
Base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.2.1.min.js" crossorigin="anonymous" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" crossorigin="anonymous" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" crossorigin="anonymous" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'event/css/custom.css' %}">
<title>Django Project</title>
</br>
<div class="container-fluid" style='font-family:arial'>
<center>
<h2> Welcome to the django website!</h2>
</center>
</div>
{{ form.media }}
</head>
<!-- body of the text -->
<body>
{% if messages %}
{% for messages in messages %}
{{ message }}
{% endfor %}
{% endif %}
{% if user.is_authenticated %}
<nav class="navbar navbar-expand-md navbar-dark bg-dark sticky-top">
<div class="navbar-nav">
<a class="nav item nav-link active" href="{% url 'event:home' %}">Home</a>
<a class="nav item nav-link" href="{% url 'profiles:profile' %}">Profile</a>
<a class="nav item nav-link" href="{% url 'profiles:edit' %}">Edit profile</a>
<a class="nav item nav-link" href="{% url 'event:create' %}">Create</a>
<a class="nav item nav-link" href="{% url 'profiles:logout' %}">Logout</a>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-success" type="submit">Search</button>
</div>
{% else %}
Login
Register
{% endif %}
</nav>
{% block content %}
{% endblock %}
</body>
</html>
Models.py
class Event(models.Model):
title = models.CharField(max_length=100)
link = models.TextField()
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
image = models.ImageField(default='default.jpg', upload_to='event_images')
image_thumbnail = ImageSpecField(source='image',
processors=[ResizeToFill(100, 100)],
format='JPEG',
options={'quality': 60})
start = models.DateField(blank=True, null=True)
start_time = models.TimeField(blank=True, null=True)
end = models.DateField(blank=True, null=True)
end_time = models.TimeField(blank=True, null= True)
description = HTMLField('description')
tags = models.ManyToManyField(Tags)
subject = models.ManyToManyField(Subject)
attendees = models.ManyToManyField(User, related_name = 'attendees', blank=True)
def __str__(self):
return f'{self.title}'
def get_absolute_url(self):
return reverse('event:detail', kwargs={'pk': self.pk})
Thanks everyone in advance,
All help will be greatly appreciated!
You may have deleted your action. Try adding the url back?
<form method="post" action="{% url "event:create" %}" enctype="multipart/form-data">
I had a problem like this too. I solved it by getting rid of a div tag containing a bootstrap class (<div class="form-group>" to be more precise) located around my form.
same problem existed for me also , the silly mistake you have done is the button thing in your create.html file , replace that with input tap with type submit and class btn , button doesn't submit request
Try this :
<input type="submit" class="btn btn-primary" value="Submit">
i know its bit late but this may seem helpful
I am trying to figure out how can I use datepicker with django-filter. I have tried a bunch of widgets but it's not working. Any suggestions will be appreciated!
I want to use datepicker for the row_date search filter.
filters.py
from home2.models import AvailstaticCopy
from django import forms
import django_filters
class DateInput(forms.DateInput):
input_type = 'date'
class AvailFilter(django_filters.FilterSet):
class Meta:
model = AvailstaticCopy
widgets = {'row_date': DateInput(),}
fields = ['row_date', 'director','manager','analyst',]
This is my template
{% load widget_tweaks %}
<form method="get">
<div class="well">
<h4 style="margin-top: 0">Filter</h4>
<div class="row">
<div class="form-group col-sm-4 col-md-3">
{{ filter.form.row_date.label_tag }}
{% render_field filter.form.row_date class="form-control" %}
</div>
<div class="form-group col-sm-4 col-md-3">
{{ filter.form.director.label_tag }}
{% render_field filter.form.director class="form-control" %}
</div>
<div class="form-group col-sm-8 col-md-6">
{{ filter.form.manager.label_tag }}
{% render_field filter.form.manager class="form-control" %}
</div>
<div class="form-group col-sm-8 col-md-6">
{{ filter.form.analyst.label_tag }}
{% render_field filter.form.analyst class="form-control" %}
</div>
<div class="form-group col-sm-8 col-md-6">
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-search"></span> Search
</button>
</div>
</div>
</div>
</form>
type="date" can help you without any widget (depends of browser):
class AvailFilter(django_filters.FilterSet):
row_date = django_filters.DateFilter(widget=DateInput(attrs={'type': 'date'}))
also if you need date range filter, you can use DateFromToRangeFilter instead of DateFilter
It is not very clear what kind of datepicker you think of, but I assume you'd like to have something like this:
jQuery UI Datepicker
I hope you know how to use a third party JavaScript library. That should be out of the scope of this question.
Once you have set up your project to use jQuery UI you can change your filters.py:
class AvailFilter(django_filters.FilterSet):
row_date = django_filters.DateFilter(
widget=DateInput(
attrs={
'class': 'datepicker'
}
)
)
class Meta:
# keep everything but the line widgets
Any widget you use accepts a keyword argument attrs which takes a dictionary, where you can specify all attributes of an HTML tag.
Now when you render row_date it should output something like this:
<input type="date" class="datepicker" ... />
To provide another answer similar to cezar's answer, I did it this way below with my filter and template codes.
filter.py
import django_filters
from .models import Product
from django import forms
class ProductFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='icontains')
price = django_filters.NumberFilter()
# using jquery
djfdate_time = django_filters.DateFilter(
lookup_expr='icontains',
widget=forms.DateInput(
attrs={
'id': 'datepicker',
'type': 'text'
}
)
)
class Meta:
model = Product
fields = ['name', 'djfdate_time','price']
base.html
{% load static %}
<html>
<head>
<link rel="stylesheet" type="text/css" href="{% static 'css/search.css' %}">
<title></title>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div id="header">
<h1 ><a class="searchtitle" href="/">Django Filter Example</a></h1>
</div>
<div id="content">
{% block content %}
{% endblock %}
</div>
<script>
$( function() {
$( "#datepicker" ).datepicker();
} );
</script>
</body>
</html>
base_extension.html
{% extends "base.html" %}
{% load my_templatetags %}
{% block content %}
<form action="" method="get">
<div>Name{{ filter.form.name }}</div>
<div>Price{{ filter.form.price }}</div>
<div>Date_Time{{ filter.form.djfdate_time }}</div>
<input type="submit" />
</form>
{% for obj in dataqs.object_list %}
{{ obj.name }}
<div>
<li>${{ obj.price }}</li>
<li> {{ obj.djfdate_time|date:'m-d H:i:s.u' }}</li>
</div>
{% endfor %}
{% endblock %}