I have a model for the profile in it there are different fields like CharField and also URLField but on the page, the styles are getting applied to the input of other fields but are not getting applied to the input of URLField
here is my models.py:
and here is my forms.py:
class ProfileForm(ModelForm):
class Meta:
model = Profile
fields = [
"name",
"email",
"username",
"location",
"bio",
"short_intro",
"profile_image",
"social_github",
"social_twitter",
"social_linkedin",
"social_youtube",
"social_website",
]
def __init__(self, *args, **kwargs):
super(ProfileForm, self).__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs.update({"class": "input"})
and here is my HTML:
{% extends 'main.html' %}
{% block content %}
<!-- Main Section -->
<main class="formPage my-xl">
<div class="content-box">
<div class="formWrapper">
<a class="backButton" href="{% url 'account' %}"><i class="im im-angle-left"></i></a>
<br>
<form action="{% url 'edit-account' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="form__field">
<label for="formInput#text">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %}
<input class="btn btn--sub btn--lg my-md" type="submit" value="Submit" />
</form>
</div>
</div>
</main>
{% endblock %}
and here is an example of gif of what's happening:
Please answer how can I apply the same styles on the input of URLField as well
Related
I'm trying to access the instance of the forms in a formset, but it is not working. I CAN access them using the variable notation, as in {{ form }}, but not in code, as in {% url 'section' form.instance.pk %}. I need to iterate through the forms in the formset along with the corresponding model instance.
My view:
# views.py
def sec(request, companyurl):
company = get_if_exists(Company, author=request.user)
SectionFormSet = modelformset_factory(Section, form=SectionForm, can_delete=True)
sections = Section.objects.filter(company=company).order_by('order')
formset = SectionFormSet(request.POST or None,
initial=[{'company': company}],
queryset=sections
context = {
'sections': sections,
'formset': formset,
}
return render(request, 'questions/sections.html', context)
My model:
# models.py
class Section(models.Model):
section = models.CharField(max_length=100)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
order = models.PositiveIntegerField(default=1000000)
show = models.BooleanField(default=True)
def __str__(self):
return self.section
My Form (I'm using django-crispy forms):
# forms.py
class SectionForm(forms.ModelForm):
class Meta:
model = Section
fields = ['company', 'section', 'show', 'order']
labels = {
'section': '',
'show': 'Show'
}
def __init__(self, *args, **kwargs):
super(SectionForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout(
Div(
Div(HTML("##"), css_class = 'my-handle col-auto'),
Div('section', css_class='col-3'),
Div('show', css_class = 'col-auto'),
Div('DELETE', css_class = 'col-auto'),
Field('company', type='hidden'),
Field('order', type='hidden'),
css_class='row',
),
)
My template (this is where the problem is seen):
<form action="#" method="post">
{% csrf_token %}
{{ formset.management_form }}
<div id="simpleList" class="list-group">
{% for fo in formset %}
<div class="list-group-item hold">
{% crispy fo %}
<!-- TESTING TO SEE IF THIS WORKS, AND IT DOES! -->
{{ fo.instance }} + {{ fo.instance.pk }} + {{ fo.instance.section }}
<!-- THE PROBLEM OCCURS WHEN THIS IS ADDED -->
<a href="{% url 'section' fo.instance.pk fo.instance.section %}">
{{ fo.instance }}
</a>
<!-------------------------------------------->
<input type="hidden" name="order" value="{{ section.pk }}">
{% for hid in fo.hidden_fields %}
{{ hid }}
{% endfor %}
</div>
{% endfor %}
<button type="submit" class="btn btn-outline-primary">Save changes</button>
</form>
When I add the <a href="{% url 'section' fo.instance.pk fo.instance.section %}>link</a> line I get
Reverse for 'section' with arguments '(None, '')' not found. 1 pattern(s) tried: ['section/(?P<pk>[0-9]+)/(?P<section>[^/]+)\\Z']
The error is clear. fo.instance.pk is None and fo.instance.section is an empty string. Yet when I remove the anchor tag, the line above appears and shows the correct values for both of these. I think I know the difference in how the {{ }} and the {% %}, and I thought I knew how model form instances were tied to the model, but I am missing something.
Thanks for any help.
Formsets create blank forms
The answer was staring me in the face, when I printed the results. The last form, a blank, of course was giving me None and an empty string, since it had no data to fill it with. Thus the simple solution is to check for this before trying to form the url with the information. Therefore, this has nothing to do with the differences between {{ }} and {% %} nor form instances.
{% for fo in formset %}
<div class="list-group-item hold">
{% crispy fo %}
<!-- TESTING TO SEE IF THIS WORKS, AND IT DOES! -->
{{ fo.instance }} + {{ fo.instance.pk }} + {{ fo.instance.section }}
<!-- THE PROBLEM OCCURED WHEN THIS WAS ADDED -->
<!-- THE SIMPLE SOLUTION: --------------------->
{% if fo.instance.pk %}
<a href="{% url 'section' fo.instance.pk fo.instance.section %}">
{{ fo.instance }}
</a>
{% endif %}
<!-------------------------------------------->
<input type="hidden" name="order" value="{{ section.pk }}">
{% for hid in fo.hidden_fields %}
{{ hid }}
{% endfor %}
</div>
{% endfor %}
<button type="submit" class="btn btn-outline-primary">Save changes</button>
</form>
Stumped as to why my template isn't showing my custom password reset form.
Here is code:
forms.py
class CustomPasswordResetForm(PasswordResetForm):
def __init__(self, *args, **kwargs):
super(CustomPasswordResetForm, self).__init__(*args, **kwargs)
email = forms.EmailField(
label='', widget=forms.EmailInput(attrs={
'placeholder': 'placetest#test.com',
'class': 'form-field', }))
Views.py
class PasswordResetView(auth_views.PasswordResetView):
form_class = CustomPasswordResetForm
template_name = 'password_reset.html'
urls.py
urlpatterns = [
path('login/', LoginView.as_view(), name='login'),
path('password_reset', PasswordResetView.as_view(), name='password_reset'),
path('login_success/', login_success, name='login_success'),]
Template
{% load static %}
{% block title %}Home{% endblock %}
{% block content %}
<div class="form-container" id="pwrest">
<div class="form-title">
<h2>Enter your email address</h2>
</div>
<form method="POST">
{% csrf_token %}
<p>email</p>
<div>{{ form.email }}</div>
<input class="submit-button" type="submit" value="Send me instructions!">
</form>
</div>
</div>
{% endblock %}
CSS
.form-field{
width: 300px;
height:30px;
margin-bottom:5px;
margin-top:5px;
border:none;
border-radius: 5px;
background-color:whitesmoke;
}
Rendered HTML
<div class="form-title">
<h2>Enter your email address</h2>
</div>
<form method="POST">
<input type="hidden" name="csrfmiddlewaretoken" value="TOKEN">
<p>email</p>
<div><input type="email" name="email" autocomplete="email" maxlength="254" required id="id_email"></div>
<input class="submit-button" type="submit" value="Send me instructions!">
</form>
</div>
</div>
When I view the template in my browser, I am seeing the form field as the default, its almost like its just not recognizing the CSS class.
I'm not sure what I've missed.
.
I am trying to create a form using django and css.
views.py
from django.shortcuts import render
from .forms import ContactForm
def home(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
pass
else:
form = ContactForm()
return render(request, 'home.html', {'form':form})
forms.py
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length = 30)
email = forms.EmailField(max_length = 254)
message = forms.CharField(max_length = 2000, widget = forms.Textarea(),help_text = "Write Your Message here")
def clean(self):
cleaned_data = super(ContactForm, self).clean()
name = cleaned_data.get('name')
email = cleaned_data.get('email')
message = cleaned_data.get('message')
if not name and not email and not message:
raise forms.ValidationError('You have to write something!')
When I try to add the form to my html page like the following it doesn't show up. Just the button shows up, no form fields -
{% extends 'store/main.html' %}
{% load static %}
{% block content %}
<h3>Store</h3>
<form method = "post" novalidate>
{% csrf_token %}
{{ form }}
<button type='submit'>Submit</button>
</form>
{% endblock content %}
If I do css form instead it obviously show up the way it should.
{% extends 'store/main.html' %}
{% load static %}
{% block content %}
<h3>Store</h3>
<form>
<label for="fname">First Name</label>
<input type="text" id="fname" name="fname">
<button type='submit'>Submit</button>
</form>
{% endblock content %}
So I decided to add the form fields individually to the css form. Where does the {{form.name}} or {{form.email}} tag go?
EDIT:
Hey Vivek, the contact form code is this -
class ContactForm(forms.Form):
name = forms.CharField(max_length = 30)
email = forms.EmailField(max_length = 254)
message = forms.CharField(max_length = 2000, widget = forms.Textarea(),help_text = "Write Your Message here")
The html template looks like this-
{% extends 'store/main.html' %}
{% load static %}
{% block content %}
<h3>Store</h3>
<form method = "post" novalidate>
{% csrf_token %}
<label class="float-left" for="name">Name</label>
{{ form.name }}
<button type='submit'>Submit</button>
</form>
{% endblock content %}
Thanks for any input.
Accessing form fields individually will make you to render the form errors individually as well. {{form}} encapsulates everything:- Form fields , errors, non_field_errors..So if you have to access the fields individually do not forget to add the form errors.
I have written a sample code which will server the purpose.
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger" style="text-align:left">
<ul>
{% for field in form %}
{% for error in field.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="form-row">
<div class="col-md-4 mb-3">
<label class="float-left" for="id_name">Name</label>
{{ form.name }}
</div>
<div class="col-md-8 mb-3">
<label class="float-left" for="id_email">Email ID</label>
{{ form.email }}
</div>
</div>
<br>
<input type="submit" class="btn btn-primary" value="Pay" id="submit">
</form>
I have the following:
forms.py
class StoreSettingsForm(ModelForm):
enable_repricer = forms.BooleanField(required=True)
enable_ignore_min_price = forms.BooleanField(required=True)
class Meta:
model = Store
fields = '__all__'
exclude = ['user']
models.py
class Store(models.Model):
user = models.ForeignKey(User, models.SET_NULL, blank=True, null=True)
store_name = models.CharField(max_length=100, blank=False)
...
enable_repricer = models.BooleanField(default=False)
enable_ignore_min_price = models.BooleanField(default=False)
template.html
<form method="post">
{% csrf_token %}
<h4>Repricer Settings</h4>
<div class="row">
{{ form.non_field_errors }}
<div class="fieldWrapper col s4">
{{ form.enable_repricer.errors }}
<label for="{{ form.enable_repricer.id_for_label }}">Enable Repricer:</label>
{{ form.enable_repricer }}
</div>
<div class="fieldWrapper col s4">
{{ form.enable_ignore_min_price.errors }}
<label for="{{ form.enable_ignore_min_price.id_for_label }}">Allow Repricer to ignore min_price:</label>
{{ form.enable_ignore_min_price }}
</div>
<div class="fieldWrapper col s4">
{{ form.repricer_factor.errors }}
<label for="{{ form.repricer_factor.id_for_label }}">Repricer aggressiveness factor (1-100):</label>
{{ form.repricer_factor }}
</div>
</div>
<input class="btn" type="submit" value="Submit">
</form>
</div>
view.py
class StoreSettingsView(View):
template_name = 'store_settings.html'
def get(self, *args, **kwargs):
store = Store.objects.get(id=kwargs['id'])
data = {
'store_name': store.store_name,
'store_email': store.store_email,
...
'enable_ignore_min_price': store.enable_ignore_min_price,
'enable_repricer': store.enable_repricer,
'repricer_factor': store.repricer_factor,
}
form = StoreSettingsForm(initial=data)
return render(self.request, self.template_name, {
"store": store,
"form": form,
})
It does not show up in the form. All field are showing on the page but not the 2 boolean fields. The labels are showing and in the HTML.
I have excluded many fields from the code blocks to make it more easy to read.
I was with this problem and I solved it doing that:
#----- My error was caused by Materialize css ----#
Not showing checkbox
<form>
{% for field in form %}
{{field.label_tag}}<br>
{{field}}
<br>
<br>
{% endfor %}
</form>
Using Materialize, You must have a span tag in your label:
Example in Materialize doc:
<label>
<input type="checkbox" class="filled-in" checked="checked" />
<span>Filled in</span>
</label>
I solved the problem refacting to the Materialize's doc structure:
<form>
{% for field in form %}
<label>
{% if field.label == "colorida" %} <!-- 'colorida' is my boolean field -->
{{field}}
<span>{{field.label}}</span> <!-- if boolean field, span must be after input (in materialize) -->
{% else %}
<span>{{field.label}}</span> <!-- description before input if not boolean field -->
{{field}}
{% endif %}
</label>
<br>
<br>
{% endfor %}
</form>
Test your example on a page without any CSS, the problem probably is caused by CSS
Ok. When typing the question something arose to me. What if.... and yes that was it. In some way my CSS is disabling the checkbox and i really do not know why. When removing the CSS it works fine. Sorry.
I have a very simple ModelForm in my app that looks like this:
# ModelForm
class ProductForm(ModelForm):
class Meta:
model = MyModel
exclude = ['created', 'last_modified', 'serial_number']
# Model
class BaseModel(models.Model):
created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
last_modified = models.DateTimeField(auto_now=True, blank=True, null=True)
class MyModel(BaseModel):
product = models.TextField(verbose_name='Product Name')
serial_number = models.TextField(verbose_name='Serial Number')
And a form that looks like this:
# Form
<form method="POST" action="{% url some_url %}">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{% for field in form %}
{% if field.errors %}
<div>{{ field.errors }}</div>
{% endif %}
<div>
{{ field.label_tag }}:
{{ field }}
</div>
{% endfor %}
{% endfor %}
<div class="actions">
<input class="button submit focus" type="submit" value="{% trans "Save" %}" />
</div>
</form>
When I check out the view using this, I just see a colon (:) followed by the textfield: The label is gone.
According to the documentation for ModelForm:
In addition, each generated form field has attributes set as follows:
...
The form field’s label is set to the verbose_name of the model field, with the first character capitalized.
What mistake have I made?
I am using Django 1.4.1 if it matters.
You have to put the field label inside a <label> tag. So:
<div>
<label for="id_{{field.html_name}}">{{field.label}}:</label>
{{ field }}
</div>
The only solution I managed to find that still allowed me to separate each row of the form was doing the following:
<form method="POST" action="{% url some_url %}">
{% csrf_token %}
{{ formset.as_ul }}
<div class="actions">
<input class="button submit focus" type="submit" value="{% trans "Save" %}" />
</div>
</form>
... the key piece being the {{ formset.as_ul }} instead of iterating through each field.
As for why the other listed solution (or the solution in the documentation) didn't work, I will remain baffled.