Django forms - how to add labels inside boxes? - django

I have simple django- form:
class ContactUsForm(forms.ModelForm):
class Meta:
model = Contact
fields = ('subject', 'email', 'message')
widgets = {'time': forms.HiddenInput()}
labels = {
'subject': 'my_subject',
'email': 'my_email',
'message': 'my_message',
}
Model:
class Contact(models.Model):
email = models.EmailField(max_length=100)
subject = models.CharField(max_length=100)
message = models.TextField()
time = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.message
And html:
<h2 class="mb-5">Contact</h2>
{% load crispy_forms_filters static %}
<form method="POST" class="post-form">{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-outline-secondary">Send</button>
</form>
How to remove labels above boxes and put it inside? Is it possible to do it with crispy?

Try this !
class ContactUsForm(forms.ModelForm):
subject = forms.CharField(label='Subject', widget=forms.TextInput(attrs={'placeholder': 'Subject'}))
email = forms.EmailField(label='Email', widget=forms.TextInput(attrs={'placeholder': 'Email'}))
message = forms.TextField(label='Message', widget=forms.TextInput(attrs={'placeholder': 'Message'}))
class Meta:
model = Contact
fields = ('subject', 'email', 'message')

This feature is not available in crispy forms. The question below shows a dry way of achieving this using the init method
Use field label as placeholder in django-crispy-forms

Related

OneToOne related other model field converted to boolean field check box in form to show or hide model fields doesn’t work

I have these two django blog models in models.py
`
class Snippet(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
code = models.TextField()
...
class Post(models.Model):
# id = models.AutoField(primary_key=True) # the same field in comment model for multi-inheritance (post_id)
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, primary_key=True)
slug = models.SlugField(max_length=200, db_index=True, unique=True, editable=False) # add unique=True in slug (never repeat)
title = models.CharField(max_length=200, db_index=True, default='')
tag = models.ManyToManyField(Tag, blank=True, help_text="Select a tag for this post", related_name='post_tags')
snippet = models.OneToOneField(Snippet, on_delete=models.CASCADE, related_name='post_snippets')
...
and i have forms to add new post as follows
class PostModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return "Post #%s) %s" % (obj.id, obj.title)
class SnippetForm(forms.ModelForm):
post = PostModelChoiceField(queryset=Post.objects.all())
class Meta:
model = Snippet
fields = '__all__'
class PostForm(forms.ModelForm):
class Meta:
model = Post
#fields = '__all__'
#fields = ['title', 'tag', 'maintainer', 'post_img', 'content', 'snippet', 'genre', 'language', 'video', 'post_type', 'urls', 'views', 'status' ]
labels = {'snippet': _('Add Code'),}
exclude = ('creator', 'slug',)
widgets = {
'snippet': forms.CheckboxInput(attrs={'type': 'checkbox', 'class': 'checkbox', 'id': 'post-snippet'})
}
def clean(self):
snippet = self.cleaned_data.get('snippet')
if snippet:
self.fields_required(snippet.title, snippet.code, snippet.title, snippet.linenos, snippet.language, snippet.style, snippet.highlighted) # ['title', 'code', 'linenos', ....]
else:
self.cleaned_data['snippet'] = False
return self.cleaned_data
def __init__(self, *args, **kwargs):
super(PostForm, self).__init__(*args, **kwargs)
self.queryset = Post.objects.filter(snippet=True)
and views logic to render template
def add_post(request):
if request.method == 'POST':
post_form = PostForm(request.POST, request.FILES, instance=request.user)
snippet = post_form.cleaned_data['snippet']
if snippet:
#snpt = modelformset_factory(Snippet, fields=('title', 'code', 'linenos', 'language', 'style', 'highlighted'))
snpt = Snippet.objects.create(post = request.post, snippet_id = request.post.id)
snippet_form = SnippetForm(request.POST, instance=snpt)
if post_form.is_valid() and snippet_form.is_valid():
post = post_form.save(commit=False)
snpt = snippet_form.save(commit=False)
post.creator = request.user
post.snippet = snpt
post.slug = slugify(post_form.cleaned_data['title'])
post.save() and snpt.save()
obj = post_form.instance
alert = True
return redirect('blog:post_list')
#return render(request, "add_post.html",{'obj':obj, 'alert':alert})
#return HttpResponseRedirect('blog/post_list/success/')
else:
post_form = PostForm()
return render(request, 'blog/add_post.html', {'form': post_form})
`
Now i can’t get the snippet fields in my template when i tick the check box in the template
Here is the form
<form method='POST' class="form" enctype='multipart/form-data'>
{{ form.non_field_errors }} {% csrf_token %} {% for field in form %}
<div class="apply">
{% if field.errors %}
<ol>
{% for error in field.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %} {% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %} {% bootstrap_form form %}
<button class="boxed-btn3 w-100" type="submit">Post</button>
</form>
what’s wrong in this logic why the snippet form doesn’t show up in the template and how to get it live immediately when i check the boolean field add code (snippet) in the page form
please help me
i tried to get all the Snippet model fields into add post model form to show all fields in one form
but can't get the fields while i have all post model fields rendered well but when i checked the
check box field snippet that has been converted into boolean in post form , nothing happens

Many to many fields in widget form

I have problem with display many to many field in form widget.
Category is not display in template.
Title is ok (is display) but category isn't - category is empty.
What can I do to display many to many fields in my template form with multiplechoice checkboxes?
Why I cant display article categories in widget form?
MODELS.py
article model:
class Article(Created, HitCountMixin):
title = models.CharField(max_length=120)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
category = models.ManyToManyField(ArticleCategory, related_name='articles')
category model:
class ArticleCategory(Created):
category_name = models.CharField(max_length=128)
slug = models.SlugField(null=False, unique=False)
VIEWS:
class UpdateArticleView(LoginRequiredMixin, UpdateView):
template_name = 'news/update_article.html'
form_class = EditArticleForm
model = Article
def get_success_url(self):
pk = self.kwargs["pk"]
slug = self.kwargs['slug']
return reverse_lazy("news:article_detail", kwargs={'pk': pk, 'slug': slug})
FORMS.py
class AddArticleForm(forms.ModelForm):
title = forms.CharField(
label="Tytuł",
max_length=120,
help_text="Tytuł newsa",
widget=forms.TextInput(attrs={"class": "form-control form-control-lg pr-5 shadow p-1 mb-1 bg-white rounded"}),
required=True,
)
category = forms.MultipleChoiceField(
widget=forms.CheckboxSelectMultiple,
)
And in my HTML TEMPLATE:
<form method="post" enctype='multipart/form-data'>
{% csrf_token %}
{{ form.media }}
{# {% crispy form %}#}
{{ form|crispy }}
<button type="submit" class="btn btn-outline-primary">EDYTUJ NEWS</button>
</form>
Your form_class in your view is a EditArticleForm, so you should be careful to use the correct form.
The form field for a ManyToManyField is normally a ModelMultipleChoiceField [Django-doc], but it is not necessary to specify the form field anyway. You can make use of the widgets option:
class EditArticleForm(forms.ModelForm):
title = forms.CharField(
label='Tytuł',
max_length=120,
help_text='Tytuł newsa',
widget=forms.TextInput(
attrs={'class': 'form-control form-control-lg pr-5 shadow p-1 mb-1 bg-white rounded'}
),
required=True,
)
class Meta:
model = Article
widgets = {
'category': forms.CheckboxSelectMultiple
}
you can customize the label with:
class EditArticleForm(forms.ModelForm):
title = forms.CharField(
label='Tytuł',
max_length=120,
help_text='Tytuł newsa',
widget=forms.TextInput(
attrs={'class': 'form-control form-control-lg pr-5 shadow p-1 mb-1 bg-white rounded'}
),
required=True,
)
class Meta:
model = Article
widgets = {
'category': forms.CheckboxSelectMultiple
}
labels = {
'category': 'label of category'
}

How to have additional field besides the fields in the model in ModelForm

I have a model named Customer and modelForm named Customer, but in my form i need more fields than the fields in Model. For example i want a confPass field in my ModelForm.
Code for Model:
class Customer(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField(max_length=100, unique=True)
mobile_no = models.CharField(unique=True, validators=[validate_mobile], max_length=10)
state = models.CharField(choices=STATES, max_length=2)
city = models.CharField(max_length=20)
password = models.CharField(max_length=256)
def __str__(self):
return self.email
class CustomerForm(ModelForm):
class Meta:
model = Customer
fields = ['name', 'email', 'mobile_no', 'state', 'city', 'password']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['name'].widget.attrs.update({'placeholder': 'Enter Name', 'class': 'form-control'})
self.fields['email'].widget.attrs.update({'placeholder': 'Enter Email', 'class': 'form-control'})
self.fields['mobile_no'].widget.attrs.update({'placeholder': 'Enter Mobile Number ', 'class': 'form-control'})
self.fields['state'].widget.attrs.update({'class': 'form-control'})
self.fields['city'].widget.attrs.update({'placeholder': 'Enter City', 'class': 'form-control'})
self.fields['password'].widget.attrs.update({'class': 'form-control'})
Just add the field to your CustomerForm class and include it in fields list:
class CustomerForm(ModelForm):
confPass = forms.CharField()
class Meta:
model = Customer
fields = ['name', 'email', 'mobile_no', 'state', 'city', 'password', 'confPass']
I had to do this for a GenericRelation field, 'task'. I wanted to add a field that was in the model but wouldn't display in the ModelForm. I was able to update the field only using the shell. I added an tag after the form and then processed the response in the def form_valid() function. My problem was that I have a task_app that I use for different models, so I needed a GenericRelation.
views.py
class ProjectModelUpdateView(UpdateView):
model = ProjectModel
# fields = '__all__'
form_class = ProjectModelForm
success_url = '/projects_app/'
def form_valid(self, form):
form.instance.updated_by = self.request.user
project = ProjectModel.objects.get(id=form.instance.id)
project.task.create(created_by=self.request.user, task=self.request.POST['task'])
return super().form_valid(form)
HTML
<form method="post">
{% csrf_token %}
{% for field in form %}
<label class="control-label" for="{{ field.auto_id }}">{{ field.label }}</label>
<div class="col-sm-5 border rounded form-outline">
{{ field }}
</div>
{% endfor %}
<label class="control-label" for="id_task">Task</label>
<div class="col-sm-5 border rounded form-outline">
<input type="text" name="task" maxlength="64" class="form-control" id="id_task">
</div>
<br>
<input type="submit" value="Save">
</form>

Checkboxes and Radio buttons in Django ModelForm

Welcome friends,
I'm a newbie in Django. I need your help. Seriously.
I want to add checkboxes and radio button in my form.
Any help will be appreciated.
models.py
from django.db import models
from shop.models import Product
class Order(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
address = models.CharField(max_length=250)
postal_code = models.CharField(max_length=20)
city = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
class Meta:
ordering = ('-created',)
def __str__(self):
return 'Order {}'.format(self.id)
def get_total_cost(self):
return sum(item.get_cost() for item in self.items.all())
forms.py
from django import forms
from .models import Order
class OrderCreateForm(forms.ModelForm):
class Meta:
model = Order
fields = ['first_name', 'last_name', 'email', 'address', 'postal_code', 'city']
create.html
{% extends "shop/base.html" %}
{% block title %}
Checkout
{% endblock %}
{% block content %}
<h1>Checkout</h1>
<form action="." method="post" class="order-form">
{{ form.as_p }}
<p><input type="submit" value="Place order"></p>
{% csrf_token %}
</form>
{% endblock %}
Any suggestions are welcome.Please help.
UPDATE
How to add select option ?
you can do something like this
CHOICES=[('item1','item 1'),
('item2','item 2')]
class OrderCreateForm(forms.ModelForm):
postal_code = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect())
....
class Meta:
model = Order
fields = ['first_name', 'last_name', 'email', 'address', 'postal_code', 'city']
similarly, you can do for the other field also
and for checkbox, you can define it as a BooleanFileld and you can use
{{ form.paid }}
in you template.
The form will be rendered with the field types you define in the model:
BooleanField is rendered as a checkbox, paid in your case.
ChoiceField can be rendered as radio buttons with the appropiate widget.
You can redefine the widgets in class OrderCreateForm:
CHOICES = [('option1','label 1'), ('option2','label 2')]
some_field = forms.ChoiceField(choices=CHOICES,widget=forms.RadioSelect())

Remove up and down arrows from Django decimal ModelForm field

My decimal ModelForm fields are being displayed with an "up/down arrows" within the field that increases/descrease the field's values.
Any feedback on how I could remove/hide those arrows?
Form:
class PriceAssessment1Form(forms.ModelForm):
class Meta:
model = Component
fields = ['size_height','size_width','size_length','weight','base_material_price']
Model
class Component(models.Model):
name = models.CharField(max_length=255)
created_date= models.DateTimeField(default=datetime.now)
user = models.ForeignKey(User)
price_assessment_started = models.BooleanField(default=False)
size_height = models.DecimalField(null=True,blank=True, max_digits=9, decimal_places=2)
size_width = models.DecimalField(null=True,blank=True, max_digits=9, decimal_places=2)
size_length = models.DecimalField(null=True,blank=True, max_digits=9, decimal_places=2)
weight = models.DecimalField(null=True,blank=True, max_digits=9, decimal_places=2)
base_material_price = models.DecimalField(null=True,blank=True, max_digits=9, decimal_places=2)
Template
<form action="{% url 'portal_price_assessment' component_id %}" method="post"> {% csrf_token %}
<div>
<div>size_height {{ form.size_height }}</div>
<div>size_width {{ form.size_width }}</div>
<div>size_length {{ form.size_length }}</div>
<div>weight {{ form.weight }}</div>
<div>base_material_price {{ form.base_material_price }}</div>
</div>
<div style="margin-top:18px;">
Cancel
<button class="btn" type="submit" > Save & Close</button>
</div>
</form>
You can override the ModelForm field to use whatever widget you would prefer like so:
class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ('name', 'title', 'birth_date')
widgets = {
'name': TextInput(attrs={'placeholder': 'That dude cray'}),
}
Example got from the django docs Overriding ModelForm fields
I found the answer here: Can I hide the HTML5 number input’s spin box?
The "arrows" are called "spinners"