I am using the Django Crispy forms and a Foreignkey field. I am using a foreignkey to get a list of all contacts. When creating a new form, I`ve got a very long list of contact to choose from. What I would like to do is to search the contact in a searchbox. At the moment, I can not use this feature as there are too many contacts to search. Is there a way to add a search box in the forms html? What would be the django crispy forms field to modify?
forms.py
class InvoiceForm(forms.ModelForm):
class Meta:
model = Invoice
fields = ['name','contact','company','terms','due_date','invoice_date','notes','draft']
def __init__(self, *args, **kwargs):
super(InvoiceForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = True
self.helper.layout = Layout(
Row(
Column('name', css_class='form-group col-md-2 mb-0'),
Column('contact', css_class='form-group col-md-2 mb-0'),
Column('company', css_class='form-group col-md-2 mb-0'),
css_class='form-row'
),
Row(
Column('terms', css_class='form-group col-md-2 mb-0'),
Column('due_date', css_class='form-group col-md-2 mb-0'),
Column('invoice_date', css_class='form-group col-md-2 mb-0'),
css_class='form-row'
),
Fieldset('Add lines',Formset('lines')),
Row(
css_class='form-row'
),
Row(
Column('notes', css_class='form-group col-md-2 mb-0'),
Column('draft', css_class='form-group col-md-2 mb-0'),
css_class='form-row'
),
Div(
HTML("<br>"),
ButtonHolder(Submit('submit', 'Save')),
css_class='float-right',
),
Div(
HTML("<br>"),
)
)
Many thanks
In the past I've used two solutions for this problem:
https://django-autocomplete-light.readthedocs.io/en/master/
I used (for some internal project) the admin widget (Horizontal Filter?). It doesn't look very nice but it might do the job... but it feels a bit hacky
I cannot think of a way to do it just using django-crispy-forms.
Related
i want to convert any new enter user name to lowercase and check if the user is exist or now and use iexact to login in capital or small
where should determine the login uses small or capital
forms.py
class AddCompanyForm(forms.ModelForm):
"""
Add company model form
"""
name = forms.CharField(required=True)
password = forms.CharField(widget=forms.PasswordInput())
logo = forms.ImageField(required=False)
phone_number = forms.CharField(widget=forms.NumberInput())
label = forms.CharField(max_length=20)
country = forms.ModelChoiceField(queryset=Country.objects.all())
city = forms.ModelChoiceField(queryset=City.objects.all())
area = forms.ModelChoiceField(queryset=Area.objects.all())
latitude = forms.CharField(max_length=50, required=False)
longitude = forms.CharField(max_length=50, required=False)
water_source = forms.ModelChoiceField(queryset=WaterSource.objects.all())
class Meta:
model = User
fields = ['name', 'username', 'email', 'password']
def __init__(self, *args, **kwargs):
super(AddCompanyForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.layout = Layout(Row(Column('name', css_class='form-group col-md-6 mb-0'),
Column('username', css_class='form-group col-md-6 mb-0'), css_class='form-row'),
Row(Column('email', css_class='form-group col-md-6 mb-0'),
Column('password', css_class='form-group col-md-6 mb-0'), css_class='form-row'),
Row(Column('phone_number', css_class='form-group col-md-6 mb-0'),
Column('logo', css_class='form-group col-md-6 mb-0'), css_class='form-row'),
Row(Column('label', css_class='form-group col'), css_class='form-row'),
Row(Column('country', css_class='form-group col'),
Column('city', css_class='form-group col'), Column('area', css_class='form-group col'),
css_class='form-row'), Row(Column('latitude', css_class='form-group col'),
Column('longitude', css_class='form-group col'),
css_class='form-row'),
Row(Column('water_source', css_class='form-group col'), css_class='form-row'))
self.helper.layout = self.layout
views.py
class Companies(LoginRequiredMixin, UserPassesTestMixin, FormView, ListView):
"""
Company add edit delete view search paginator
"""
model = Company
template_name = 'company/index.html'
form_class = AddCompanyForm
success_url = reverse_lazy('companies:index')
object_list = Company.objects.all()
def form_valid(self, form):
user, created = User.objects.get_or_create(username=form.cleaned_data['username'],
email=form.cleaned_data['email'])
user.set_password(form.cleaned_data['password'])
user.save()
if created:
address = Address(label=form.cleaned_data['label'], city=form.cleaned_data['city'],
area=form.cleaned_data['area'], long=form.cleaned_data['longitude'],
lat=form.cleaned_data['latitude'], country=form.cleaned_data['country'])
address.save()
company = Company(owner=user, name=form.cleaned_data['name'],
phone_number=form.cleaned_data['phone_number'], logo=form.cleaned_data['logo'],
address=address, water_source=form.cleaned_data['water_source'])
company.save()
return super().form_valid(form)
am try to put this function in form to convert lowercase
def clean_username(self):
return self.cleaned_data['username'].lower()
how i can use iexact when login and where
you can match username in lowercase like this
from django.db.models.functions import Lower
input_name = form.cleaned_data['username'].lower()
User.objects.annotate(username_lower=Lower("username")).filter(username_lower=input_name)
I am using django-crispy-forms. One of the form field is multiple choice checkbox. In this checkbox i wanted to show some options as checked. How to do that.
choices are declared as:-
documents_req = (
('1', 'TC'),
('2', 'Marksheet'),
('3', 'Char Cert'),
('4', 'Caste Cert')
)
Form is created as following:-
class AddStudentForm(forms.Form):
....
....
documents_required =
forms.MultipleChoiceField(choices=documents_req,required=False,
widget=forms.CheckboxSelectMultiple)
def init(self, *args, **kwargs):
super().init(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'form-horizontal'
self.helper.form_tag = False
self.helper.label_class = 'col-lg-3'
self.helper.field_class = 'col-lg-8'
self.helper.layout = Layout(
Div(
Div('email', css_class='form-group col-sm-4 mb-0
border border-secondary'),
Div('password', css_class='form-group col-sm-4 mb-0
border border-secondary'),
Div('address_1', css_class='form-group col-sm-4 mb-0
border border-secondary'),
css_class='form-row'),
Div(
Div('address_2', css_class='form-group col-sm-4 mb-0
border border-secondary'),
Div('city', css_class='form-group col-sm-4 mb-0
border border-secondary'),
Div('state', css_class='form-group col-sm-4 mb-0
border border-secondary'),
css_class='form-row'),
Div(
Div(InlineCheckboxes('documents_required'),css_class='form-group col-sm-6 mb-0 border border-secondary'),
Div('zip_code', css_class='form-group col-sm-3 mb-0 border border-secondary'),
Div('check_me_out', css_class='form-group col-sm-3 mb-0 border border-secondary'),
css_class='form-row')
)
It is perfectly showing the checkboxes. But I wanted some choices let's say option 1 and 2 to be checked. How to achieve that.
form_field = forms.MultipleChoiceField(choices=[("1", "option 1"),("2", "optiom 2")])
I am using django crispy_forms.helper and crispy_forms.layout to create radio button with options. The label and radio button options are overlapping.
The code which i am using is :
forms.py
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, HTML, Layout, Row, Div, Fieldset,ButtonHolder,Column
from crispy_forms.bootstrap import InlineRadios, PrependedAppendedText, Div
ROUTER_OPTIONS = (
('', 'Choose router...'),
('FIP', 'First IP in range'),
('AM', 'Add Manually')
)
class DhcpForm(forms.ModelForm):
router = forms.ChoiceField(label='Router',
choices=ROUTER_OPTIONS,
initial='', widget=forms.RadioSelect)
def __init__(self, *args, **kwargs):
super(DhcpForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.layout = Layout(
Row(
Column('dhcp_member', css_class='form-group col-md-6 mb-0'),
Column('router', css_class='form-group col-md-6 mb-0'),
css_class='form-row'
)
html
{% block content %}
{% crispy form %}
{% endblock %}
The view which i am getting:
overlapped view
In your Choice field Add the style function and set the display as flex given below.
Column('router', css_class='form-group col-md-6 mb-0', style='display: flex')
I've a form named "CarForm". I 've created a "Create Form" to create car record using crispy form. I would like to ask is it possible to display the detail and update the car record using the same form?
Here is the code for CarForm:
from .models import *
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, HTML, Row, Column
from crispy_forms.bootstrap import PrependedAppendedText, PrependedText, FormActions
from django.urls import reverse
class CarForm(forms.ModelForm):
note = forms.CharField(widget=forms.Textarea())
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['note'].required = False
self.fields['policy_num'].required = False
self.helper = FormHelper()
self.helper.form_method = 'POST'
self.helper.form_action = reverse('create')
self.helper.layout = Layout(
Row(
Column('reg_num', css_class='form-group col-md-6 mb-0'),
Column('make', css_class='form-group col-md-6 mb-0'),
Column('year', css_class='form-group col-md-4 mb-0'),
Column('color', css_class='form-group col-md-4 mb-0'),
Column('cc', css_class='form-group col-md-4 mb-0'),
Column('engine_num', css_class='form-group col-md-6 mb-0'),
Column('chasis_num', css_class='form-group col-md-6 mb-0'),
css_class='form-row'
),
'note',
Row(
Column(PrependedAppendedText('price_buy', 'RM','.00'), css_class='form-group col-md-6 mb-0'),
Column(PrependedAppendedText('price_sell','RM','.00'), css_class='form-group col-md-6 mb-0'),
Column('policy_num', css_class='form-group col-md-12 mb-0'),
Column('owner_name', css_class='form-group col-md-4 mb-0'),
Column('owner_ic',css_class='form-group col-md-4 mb-0'),
Column('owner_phone', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
FormActions(
Submit('submit', 'Create'),
)
)
class Meta:
model = Car
exclude = ['date']
Code in views.py.
I've added instance in the edit function, but there is an error for all the field this field is required
def edit(request,id):
car = Car.objects.get(id=id)
form = CarForm(request.POST,instance=car)
context = { 'car':car ,'form':form }
return render(request,'cars/edit.html',context)
def update(request,id):
car = Car.objects.get(id=id)
car.reg_num = request.POST['reg_num']
car.make = request.POST['make']
car.color = request.POST['color']
car.year = request.POST['year']
car.engine_num = request.POST['engine_num']
car.chasis_num = request.POST['chasis_num']
car.note = request.POST['note']
car.price_buy = request.POST['price_buy']
car.price_sell = request.POST['price_sell']
car.policy_num = request.POST['policy_num']
car.owner_name = request.POST['owner_name']
car.owner_ic = request.POST['owner_ic']
car.owner_phone = request.POST['owner_phone']
car.save()
messages.success(request,'Car "%s" updated successfully' % car.reg_num)
return redirect('/cars/list/')
Here is the code for edit.html:
{% block title %}Edit Car Record{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<h1 align="center">Edit Car Record</h1>
{% crispy form %}
{% endblock %}
I have the following field in a Form:
<div class="form-group ">
<div class="input-group">
<input class="form-control" id="To" name="To" placeholder="To" type="text"/>
<i class="glyphicon glyphicon-map-marker form-control-feedback"></i>
</div>
</div>
which looks like
and I am trying to have a similar result using crispy-forms.
I tried
self.helper.layout = Layout(
Fieldset(
'Title',
PrependedText(
'From',
<i class="glyphicon glyphicon-map-marker"></i>
),
'To',
'Date',
ButtonHolder(
Submit('submit', 'Search', css_class='button white')
)
)
)
but I get a SyntaxError: invalid syntax.
Is it possible to add an icon as PrependedText in crispy-forms?
If not, is there any alternative?
(Edit)
Trying
self.helper.layout = Layout(
Field(PrependedText('From', HTML('<span class="glyphicon glyphicon-map-marker"></span>')), placeholder='From'),
'To',
'Date',
ButtonHolder(
Submit('submit', 'Search', css_class='button white')
)
)
does not raise any error, but no icon is shown.
self.helper.layout = Layout(
Div(HTML('''
<div class="input-group">
<input class="form-control" id="To" name="To" placeholder="To" type="text"/>
<i class="glyphicon glyphicon-map-marker form-control-feedback"></i>
</div>'''),
class="form-group")
This works with placeholders:
self.helper = FormHelper()
self.helper.form_show_labels = False
self.helper.layout = Layout(
Field(
PrependedText('email',
mark_safe('<span class="glyphicon glyphicon-envelope"></span>'),
placeholder=_("Enter Email"), autofocus="")
),
Field(
PrependedText('name',
mark_safe('<span class="glyphicon glyphicon-user"></span>'),
placeholder=_("Enter Full Name"))
),
An alternative to using glyphicons would be using similar unicode symbols:
self.helper.layout = Layout(
Field(PrependedText('From', '📌'), placeholder='From'),
Field(PrependedText('To', '📌'), placeholder='To'),
Field(PrependedText('Date', '📅'), placeholder='Date'),
FormActions(ButtonHolder(Submit('submit', 'Search', css_class='btn btn-primary')))
)
Problem here is that placer holder is for some reason not working...
Note also that appending '︎' to the unicode symbols to force that it is not rendered to emojis, as suggested here, does not seem to work.
just use django's mark_safe helper like this:
from django.utils.safestring import mark_safe
Field(PrependedText('From',
mark_safe('<span class="glyphicon glyphicon-map-marker"></span>')),
placeholder='From')