How To Provide A Class To Fields In A Django Template? - python

I was working a project on mine, in which I needed to provide a class to a field in form which is a input box, but don't know how to do so.
My Template:
{% extends 'diary/base.html' %}
{% block title %}Register{% endblock title %}
{% block content %}
{% load staticfiles %}
<link rel= "stylesheet" type= "text/css" href = "{% static 'users/register.css' %}">
<div id="login-box">
<div class="left-box">
<h1>Register</h1>
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
{% for non_field_error in form.non_field_errors %}
<p>{{ non_field_error }}</p>
{% endfor %}
{% for field in form %}
{{ field }}
{% for error in field.errors %}
<p>{{ error }}</p>
{% endfor %}
{% endfor %}
<input type="submit" value="SIGN UP" name="signup-button" class="signup-btn">
</form>
</div>
<div class="right-box">
</div>
</div>
{% endblock content %}
In this specific part:
{% for field in form %}
{{ field }}
{% for error in field.errors %}
I want to provide a class to {{ field }}.
I tried this:
{{ field(class="txtb") }}
This is how I use to provide a class in Flask, but in Django this didn't worked.
Any Help Would Be Appreciated!

django-widget-tweaks
I'm using django-widget-tweaks module for set HTML attribute in templates.
installation
install module using pip install django-widget-tweaks
add to INSTALLED_APPS in settings.py
INSTALLED_APPS = [
...
'widget_tweaks',
...
]
{% load widget_tweaks %} in templates file
usage
in templates code:
{% load widget_tweaks %}
...
{% for field in form %}
{% render_field field class="txtb" %}
...
in HTML, looks like this:
<input class="txtb" ... ...>
reference django-widget-tweaks github page for more information.
manually
Detailed description is in here
forms.py:
class YourForm(forms.ModelForm):
modelfield = forms.CharField(
...,
widget=forms.TextInput(
attrs={
'class': 'txtb'
}
}
)
class Meta:
model = ...
fields = ...
And I have a lot of information about django to simpleisbetterthancomplex.com
django-widget-tweaks also learned here

Related

MultiValueDictKeyError with modified inline template in Django admin

In Django 1.11, I have 2 models, Foo and Bar:
class Foo(models.Model):
name = models.CharField()
class Bar(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
My admin.py looks like this:
class BarInline(admin.StackedInline):
model = Bar
template = 'admin/edit_inline/list.html'
class FooAdmin(admin.ModelAdmin):
fields = ('name')
inlines = [BarInline]
I use a customised template to show the Bar inline form, because I don't want the forms, just links to the edit pages for each Bar. list.html looks like this:
{% load i18n admin_urls static %}
<div class="js-inline-admin-formset inline-group" data-inline-type="stacked">
<fieldset class="module {{ inline_admin_formset.classes }}">
<h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
{{ inline_admin_formset.formset.management_form }}
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if inline_admin_form.original or inline_admin_form.show_url %} has_original{% endif %}{% if forloop.last %} empty-form last-related{% endif %}">
<h3 style="overflow:auto"><span style="float:left">{{ inline_admin_formset.opts.verbose_name|capfirst }}: {% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %}#{{ forloop.counter }}{% endif %}</span><span style="float:right">{% if inline_admin_form.original %}Change Delete{% endif %}</span>
</h3>
</div>{% endfor %}
<div class="add-row">
Add a Bar
</div>
</fieldset>
</div>
The problem is that when I edit an existing Foo, and click Save, I get the error:
MultiValueDictKeyError at /admin/app/foo/1/change/
"'bar_set-0-id'"
EDIT: Stacktrace
If you don't want the form for the inline, the easiest approach is to not make the field(s) editable. This will render the objects with their values, but not editable in a form. The other way to display this is admin.TabularInline.
The options for inlines can be found here; https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#inlinemodeladmin-options
The option that you will likely want to enable is show_change_link
What you'd end up with is something like;
class BarInline(admin.StackedInline):
model = Bar
fields = ('name', )
readonly_fields = ('name', )
show_change_link = True
For anyone interested, I ended up extending the template. I created a file change_form.html in templates/admin/app/foo/, and overrode the after_related_objects block:
{% extends 'admin/change_form.html' %}
{% load admin_urls %}
{% block after_related_objects %}
<div class="js-inline-admin-formset inline-group">
<fieldset class="module">
{% for bar in original.bar_set.all %}
<h3>
{{ bar.name }}
Change
</h3>
{% endfor %}
</fieldset>
</div>
{% endblock %}

Problem loading a static css file with django

I'm trying to load a static css file but to no avail:
home.html:
{% extends 'base.html' %}
{% block body%}
{% load static %}
<link rel="stylesheet" href="{% static 'home/style.css' %}" type="text/css">
<div class="container">
<br/>
<form method="post">
{% csrf_token %}
{{ form.post }}
<br />
<button type="submit">Submit</button>
</form>
<h2>{{ text }}</h2>
{% for post in posts %}
<h1>{{ post.post }}</h1>
<p>Posted </b> on {{ post.created }}</p>
{% endfor %}
</div>
{% endblock %}
style.css:
.HomeForm {
size:20;
}
forms.py:
class HomeForm(forms.ModelForm):
post = forms.CharField(widget=forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': 'How are you feeling?',
'size': '20',
}
))
I have a feeling I'm loading the static file in the wrong place, whats the solution? Thanks in advance.
You are loading the css file correctly. But that is not how you apply css classes to django forms.
Firstly, You are already giving bootstrap attributes to your field in your forms.py.
Now to apply the css classes change the following.
style.css
doesnt matter what you name your classes. No need to name them same as your Form name.
.home-post {
size:30; // Increase this to see difference
}
Now in your home.html add the class to your form. (Look for the comment). So now all the elements inside this container have size attribute too.
{% extends 'base.html' %} {% block body%} {% load static %}
<link rel="stylesheet" href="{% static 'home/style.css' %}" type="text/css">
<div class="container home-post"> <!--This is how you need to apply-->
<br/>
<form method="post">
{% csrf_token %} {{ form.post }}
<br />
<button type="submit">Submit</button>
</form>
<h2>{{ text }}</h2> {% for post in posts %}
<h1>{{ post.post }}</h1>
<p>Posted on {{ post.created }}</p>
{% endfor %}
</div>
{% endblock %}
EDIT:
Looks like you're using bootstrap but don't seem to load it. Add bootstrap if you didn't already add it in your base.html

django_markdown doesn't work on my template

I'm using the module django markdown and it doesn't work on my template, but it does on django admin
My Django version is 1.8.5 and I'm using the latest version of django markdown
I followed the steps showed in the repository's README https://github.com/klen/django_markdown
setup ( add django_markdown in settings and url are both ok )
in model.py ( migrate is ok )
from django_markdown.models import MarkdownField
class MyModel(models.Model):
description = MarkdownField()
python manage.py collectstatic is ok
forms.py
class BidForm(BaseBidForm, forms.ModelForm):
class Meta:
model = Bid
fields = ('name', 'description')
description = forms.CharField(widget=MarkdownWidget())
admin.py
#admin.register(models.Bid)
class BidAdmin(admin.ModelAdmin):
formfield_overrides = {MarkdownField: {'widget': AdminMarkdownWidget}}
template .html
{% load django_markdown %}
{% for field in form %}
{% if field.html_name == 'description' %}
<div class="col-md-7">
<div class="form-group">
<label for="{{ form.description.html_name }}">{% trans "Descripción" %} <span class="red">*</span> <small class="required">(obligatorio)</small></label><br>
<textarea id="new" class="form-control {{ field.errors|yesno:'error,' }}" rows="3"
name='{{ form.description.html_name }}'
placeholder="{% trans "ejemplos" %}"
value="{% if form.description.value %}{{ form.description.value }}{% endif %}"></textarea>
{% markdown_editor "#new" %}
{% markdown_media %}
</div>
</div>
{% endif %}
{% endfor %}

Class view returns object has no attribute 'rindex' error

I'm trying to rewrite my function based view to class based view. It raises this error:
.../test/User1
'UserDetailView' object has no attribute 'rindex'
The problem is probably obvious, I'm new in class based views.
So what to do to be able get any profile using url .../test/username?
My new view:
class UserDetailView(DetailView):
model = User
def get_object(self, queryset=None):
return get_object_or_404(self.model, pk=self.kwargs["pk"])
URLS.PY:
url(r'^test/(?P<username>[a-zA-Z0-9]+)/$', views.UserDetailView(),name="user_detail"),
And template:
{% extends "base.html" %}
{% block content %}
{{ userprofile.as_p }}
{% endblock %}
My old view is this:
def get_user_profile(request, username):
user = User.objects.get(username=username)
jobs = user.jobs.all()
table = MyJobsTable(jobs)
context = {
'my_jobs': table,
"user": user
}
return render(request, 'auth/profiles/my-profile.html', context=context)
And HTML:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% load render_table from django_tables2 %}
{% block content %}
{% if user.is_authenticated %}
<h3>{% if user.userprofile.is_translator %} Prekladateľský účet: {% else %} Štandardný
účet: {% endif %}{{ user.username }} </h3>
<ul>
<li>Username: {{ user.username }}</li>
<li>First name: {{ user.first_name }}</li>
<li>Last name: {{ user.last_name }}</li>
<li>Email: {{ user.email }}</li>
<li>Telephone: {{ user.userprofile.telephone }}</li>
<li>Languages: {{ user.userprofile.languages.as_p }}</li>
{# TODO: DOPLNIT ATRIBUTY + ked je aj translator#}
</ul>
{% if user.jobs %}
<p>My Jobs</p>
{% render_table my_jobs %}
{% else %}
<p>You have no jobs</p>
{% endif %}
<form class="navbar-form navbar-right" action="/edit-profile" method="get">
<button type="submit" class="btn btn-success">Edit Your Profile</button>
</form>
<form class="navbar-form navbar-right" action="/register-as-translator" method="get">
<button type="submit" class="btn btn-success">Become A Translator</button>
</form>
{% endif %}
{% endblock %}
URLS.PY:
url(r'^profile/(?P<username>[a-zA-Z0-9]+)/$', views.get_user_profile)
The issue is in your urls.py. With a class-based view, you always need to use the as_view classmethod:
url(r'^test/(?P<username>[a-zA-Z0-9]+)/$', views.UserDetailView.as_view(), name="user_detail"),

"Enter a valid time" on Django TimeField using django-bootstrap3-datetime

I'm having issues with time validation when submitting a form using django bootstrap datetime picker. When this form is submitted, I get a "Enter a valid time." error
models.py:
class Appointment(models.Model):
date = models.DateField()
time = models.TimeField()
forms.py:
valid_time_formats = ['%P', '%H:%M%A', '%H:%M %A', '%H:%M%a', '%H:%M %a']
date = forms.DateField(
widget=DateTimePicker(options={"format": "MM/DD/YYYY",
"pickTime": False,
"showToday": True,
}))
time = forms.TimeField(
widget=DateTimePicker(options={
"pickTime": True,
"pickDate": False,
"minuteStepping": 1,
"sideBySide": True,
}),
input_formats = valid_time_formats
)
class Meta:
model = Appointment
fields = (
'date',
'time',
'duration',
'cost',
)
And if helpful, the template:
{% extends 'scheduling/base_scheduling.html' %}
{% load bootstrap3 %}
{% block title %}New Appointment{% endblock %}
{% block external %}
<link rel="stylesheet"
href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.css">
<link rel="stylesheet"
href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.js">
</script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.js">
</script>
{{ form.media }}
{% endblock %}
{% block content %}
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript %}
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
{# Display a form #}
<h1>New Appointment for {{client.full_name}}</h1>
<form action="{% url 'client_appointment_add' client.id %}" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "save" %} Submit
</button>
{% endbuttons %}
</form>
{% endblock %}
I've had same error. Setting date format in forms is not enough.
I get rid of it after properly configuring my django datetime settings.
For how to do it right see my answer here: How to format DateTimeField in Django Admin to localtime?
You will find there also link to example project with right config.
I tested this now with bootstrap3_datetime, bootstrap3 and it works, so it should work for you too.

Categories

Resources