I've got a table in a view which doesn't render css. I suppose it's a stupid error but I can't find any solution on my way :(
The View :
class ContactsTable(tables.Table):
selection = tables.CheckBoxColumn(accessor="id")
class Meta:
model = Contact
exclude = ("id", "civilite", "ad1", "ad2", "cp")
sequence =("selection", "nom", "prenom", "comments", "telport", "telfixe", "email", "ville", "regime")
def ListContacts(request):
table = ContactsTable(Contact.objects.all())
RequestConfig(request).configure(table)
return render(request, "contacts/contact_list.html", {'table': table})
The Template :
{% load render_table from django_tables2 %}
<html>
<head>
<link rel="stylesheet" href="{{ STATIC_URL }}django_tables2/themes/paleblue/css/screen.css" />
</head>
<body>
{% render_table table %}
</body>
</html>
Sorry for my poor english and noobie question.
For anyone who has the same problem, don't forget the attrs...
class ContactsTable(tables.Table):
class Meta:
model = Contact
exclude = ("id", "civilite", "ad1", "ad2", "cp")
sequence =("selection", "nom", "prenom", "comments", "telport", "telfixe", "email", "ville", "regime")
--> attrs = {"class": "paleblue"} <--
selection = tables.CheckBoxColumn(accessor="id")
Related
I am using django-tables2 with django-modeltranslation in one of my new projects. The site is using localization for english and french.
If I render the table directly in html everything works fine, but django_tables2 seems to pour everything out, ignoring the localization request.
Django-tables2 has a "localize/unlocalize" option for multilingual sites but it does not seem to work with django-modeltranslation.
Here is my setup.
models.py
class DataSet(models.Model):
name = models.CharField(max_length=255)
source = models.CharField(max_length=255, null=True)
data_type = models.CharField(max_length=255, null=True)
translation.py
#register(DataSet)
class DataSetTranslationOptions(TranslationOptions):
fields = (
"name",
"source",
"data_type",)
tables.py
class DataSetTable(tables.Table):
name = tables.Column(order_by="name")
class Meta:
model = DataSet
sequence = (
"name",
"source",
"data_type",)
unlocalize = ("id",)
localize = (
"name",
"source",
"data_type",)
datasets.html
{% load i18n %}
{% load render_table from django_tables2 %}
{% block content %}
{% render_table table %}
{% endblock content %}
This table is rendered as follows:
name
source
data_type
name_en
name_fr
source_en
source_fr
data_type_en
data_type_fr
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
Please let me know what I am missing.
I'm very early into learning Flask/WTForms, and I'm wondering why I keep getting None for form_name.field_name.data
application.py:
import os
from flask import Flask, session, render_template, request, redirect, url_for
from flask_session import Session
from wtforms import Form, PasswordField, StringField, SelectField, validators
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
app = Flask(__name__)
# Create registration form class
class RegistrationForm(Form):
username = StringField("Username")
password = PasswordField("Password")
name = StringField("Name")
email = StringField("Email Address")
city = StringField("Nearest City")
#app.route("/", methods=["GET", "POST"])
def signup():
registration_form = RegistrationForm()
if request.method == "GET":
return render_template("index.html", registration_form=registration_form)
else:
username = registration_form.username.data
password = registration_form.password.data
name = registration_form.name.data
email = registration_form.email.data
city = registration_form.city.data
# print for testing
print(registration_form.data)
print(username)
print(password)
print(name)
print(email)
print(city)
user = {
"username": registration_form.username.data,
"password": registration_form.password.data,
"name": registration_form.name.data,
"email": registration_form.email.data,
"city": registration_form.city.data
}
return render_template("success.html", user=user)
index.html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Index</title>
</head>
<body>
<h1>Index</h1>
<form action="/" method="POST">
<ul>
{% for field in registration_form %}
<li>{{ field.label }}: {{ field }}</li>
{% endfor %}
<li><input type="submit"></li>
</ul>
</form>
</body>
</html>
print(registration_form.data) prints {'username': None, 'password': None, 'name': None, 'email': None, 'city': None}, but I expect the user-input values instead of None.
Similarly, each of these prints print None, and I expect the user-input values.
print(username)
print(password)
print(name)
print(email)
print(city)
I have the same problem as [#DHerls][1], but the given solution did not work for me.
Django FilteredSelectMultiple not rendering on page
Other similar questions with solutions I tried:
Django FilteredSelectMultiple widget rendered with bootstrap
Django admin's filter_horizontal not working
Uncaught ReferenceError: django is not defined
The problem is that only half of the FilteredSelectMultiple shows up:
Things I have tried:
syncdb
checking that jQuery is running
checked for jQuery imports conflicting, but I am new to
it, so I am unsure about this.
template.html
{{ form.media }}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="{% static 'js/bootstrap.js' %}"></script>
<script src="{% static '/admin/js/jquery.init.js' %}"></script>
<script src="{% static '/js/SelectBox.js' %}"></script>
<script src="{% static '/js/SelectFilter2.js' %}"></script>
<link href="https://fonts.googleapis.com/css?family=Playfair+Display+SC" rel="stylesheet">
<link rel="shortcut icon" type="imgs/favicon.png" href="{% static 'imgs/favicon.png' %}"/>
[...]
<form action="{% url 'recipes' %}" id="add_ingredient" method="post" accept-charset="utf-8" style="width: 400px; margin-left: auto; margin-right: auto; padding: 10px 0 30px 0;" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<span class="input-group-btn">
<button class="btn btn-secondary" style="margin-left: 40%; margin-top: 20px; padding: -10px;" type="submit">Submit</button>
</span>
</form>
views.py
decorators = [login_required, transaction.atomic]
#method_decorator(decorators, name='dispatch')
class RecipeCreate(CreateView):
model = Recipe
form_class = RecipeCreateForm
template_name = 'sous/new_recipe.html'
def get_context_data(self, **kwargs):
context = super(RecipeCreate, self).get_context_data(**kwargs)
context['form'] = RecipeCreateForm()
return context
def form_valid(self, form):
self.object = form.save()
return render(self.request, 'sous/new_recipe.html', {'new_recipe': self.object })
forms.py
class RecipeCreateForm(forms.ModelForm):
name = forms.CharField(max_length=150, required=True, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '*' }))
photo = forms.ImageField(required=False, widget=forms.FileInput(attrs={'class': 'form-control'}))
cost = forms.DecimalField(required=False, min_value=0, max_digits=5, decimal_places=2, widget=forms.NumberInput(attrs={'step': 0.01, 'class': 'form-control', 'placeholder': '00.00'}))
prep_time = forms.DurationField(required=False, widget=forms.NumberInput(attrs={'step': 0.01, 'class': 'form-control', 'placeholder': 'HH.MM'}))
cook_time = forms.DurationField(required=False, widget=forms.NumberInput(attrs={'step': 0.01, 'class': 'form-control', 'placeholder': 'HH.MM'}))
ingredients = forms.ModelMultipleChoiceField(queryset=Ingredient.objects.all(), widget=FilteredSelectMultiple('Ingredient', is_stacked=False, attrs={'rows':'5'}))
class Meta:
model = Ingredient
ordering = ('order',)
fields = ['ingredients', 'name', 'cost', 'prep_time', 'cook_time', 'photo']
css = {
'all':('/admin/css/widgets.css', 'admin/css/overrides.css'),
}
js = ('/admin/jsi18n/',)
def __init__(self, parents=None, *args, **kwargs):
super(RecipeCreateForm, self).__init__(*args, **kwargs)
Using django 2.2, I was able to solve this by putting this in my
urls.py
urlpatterns = [
...
...
/* all your urls */
re_path(r'^jsi18n/$', JavaScriptCatalog.as_view(), name='javascript-catalog')
]
bottom of template
<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
forms.py
class ManageUserPermissionsForm(forms.ModelForm):
class Meta:
model = User
fields = ['permissions']
permissions = forms.ModelMultipleChoiceField(queryset=Permission.objects.all(),required=True,
widget=FilteredSelectMultiple('User Permissions',is_stacked=False))
class Media:
css = {'all': ('/static/admin/css/widgets.css',), }
views.py (you can ignore permissions required mixin, and slug_field and slug_url_kwarg
class ManageUserPermissionsView(PermissionRequiredMixin, UpdateView):
permission_required = 'manage_user'
model = User
form_class = ManageUserPermissionsForm
template_name = 'manage_permissions.html'
slug_field = 'uuid'
slug_url_kwarg = 'uuid'
I made this specifically for managing user permissions, but the queryset can be whatever you want
I have a largish base.twig file, and I want to break it up into three includes: header.twig, content.twig, and footer.twig. I'm having trouble getting the block from my child template to override the block included into my parent template and would like to know if it's even possible, and if not, what a Twig-ish solution might look like.
I've setup a simple example to illustrate the question. I'm retrieving a Wordpress page and using Timber to process the Twig templates. The PHP template that gets invoked is page-test.php:
<?
$context = Timber::get_context();
Timber::render('test_child.twig', $context);
?>
The Twig template that gets rendered is test_child.twig:
{% extends 'test_base.twig' %}
{% block content_main %}
<h1>Random HTML</h1>
{% endblock content_main %}
The parent template, test_base.twig is:
<!DOCTYPE html>
<head>
<title>Twig test</title>
</head>
<body>
{% include 'test_content.twig' %}
</body>
</html>
And finally, the included template, test_content.twig, is like this:
<div class="main">
{% block content_main %}
{% endblock content_main %}
</div>
The resulting output looks like this:
<!DOCTYPE html>
<head>
<title>Twig test</title>
</head>
<body>
<div class="main">
</div>
</body>
</html>
As you can see, the <div> has no content. What I expected was for it to contain the <h1>Random HTML</h1> fragment from test_child.twig.
Why isn't the block from test_child.twig overriding the same-named block included from test_content.twig into test_base.twig? And if the approach simply won't work, what's the best Twig-ish way of accomplishing something close?
This is indeed not possible with twig, due to the fact included files have no affinity with the templates who called them. To explain myself have a look at this snippet
{{ include('foo.twig') }}
This snippet will be parsed into PHP by the twig compiler and the code it compiles into is this
$this->loadTemplate("foo.twig", "main.twig", 6)->display($context);
Now we can investigate this further with looking at the source of Twig_Template::loadTemplate. If you have a look at that particular function we will see, that because u are passing a string to the function, the function loadTemplate will be called in the class Twig_Environment
In this last function we can cleary see that the Twig_Environment::loadTemplate function is not passing any information nor instance of the template you rendered towards the template you are including. The only thing that gets passed (by value) is the variable $context, which hold all variables you've sent from your controllller to the template you are rendering.
I'm guessing one of the main reasons this is coded as such is because included files should be reusable in any situation and should not have dependencies like a (non-existant) block to make them being rendered
TwigTemplate.php
protected function loadTemplate($template, $templateName = null, $line = null, $index = null) {
try {
if (is_array($template)) return $this->env->resolveTemplate($template);
if ($template instanceof self) return $template;
if ($template instanceof Twig_TemplateWrapper) return $template;
return $this->env->loadTemplate($template, $index);
} catch (Twig_Error $e) {
if (!$e->getSourceContext()) $e->setSourceContext($templateName ? new Twig_Source('', $templateName) : $this->getSourceContext());
if ($e->getTemplateLine()) throw $e;
if (!$line) {
$e->guess();
} else {
$e->setTemplateLine($line);
}
throw $e;
}
}
Environment.php
public function loadTemplate($name, $index = null) {
$cls = $mainCls = $this->getTemplateClass($name);
if (null !== $index) {
$cls .= '_'.$index;
}
if (isset($this->loadedTemplates[$cls])) {
return $this->loadedTemplates[$cls];
}
if (!class_exists($cls, false)) {
$key = $this->cache->generateKey($name, $mainCls);
if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
$this->cache->load($key);
}
if (!class_exists($cls, false)) {
$source = $this->getLoader()->getSourceContext($name);
$content = $this->compileSource($source);
$this->cache->write($key, $content);
$this->cache->load($key);
if (!class_exists($mainCls, false)) {
/* Last line of defense if either $this->bcWriteCacheFile was used,
* $this->cache is implemented as a no-op or we have a race condition
* where the cache was cleared between the above calls to write to and load from
* the cache.
*/
eval('?>'.$content);
}
if (!class_exists($cls, false)) {
throw new Twig_Error_Runtime(sprintf('Failed to load Twig template "%s", index "%s": cache is corrupted.', $name, $index), -1, $source);
}
}
}
As I'm not sure why you have this set-up,this would be a more twig-style setup. Please note you have to define the blocks in your base class first, because "defining" block in an extended class, tries to display the blocks of your parent and does not create a new one.
test_main.twig
<!DOCTYPE html>
<head>
<title>Twig test</title>
</head>
<body>
{% block content_main %}
{% include 'block.twig' %}
{% endblock %}
</body>
</html>
test_child.twig
{% extends "test_main.twig" %}
{% block content_main %}
{% include "test_content.twig" %}
{% endblock %}
test_content.twig
<div class="main">
Lorem Lipsum
</div>
Unfortunately this does not work with include.
I had this issue as well when I was trying to pass some SEO values from my product controller to the base template that included the meta tags.
You have to use "extends" for the inner template as well, and point your controller to use the inner template instead of the middle/layout one.
You can then define a separate block on your inner template, which can directly override the base template's block.
You can see a working example in this Fiddle (Note that the inner template is the main one)
https://twigfiddle.com/1ve5kt
I have a problem with the crispy forms framework, setting the field_class and label_class attributes is not making a difference to the layout. I am using Bootstrap3, and all of the css files can be used elsewhere on my site (ie they are being picked up successfully in the static directory).
forms.py
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
helper = FormHelper()
helper.form_class = 'form-horizontal'
helper.label_class = 'col-lg-2'
helper.field_class = 'col-lg-10'
helper.layout = Layout(
'username',
'password',
Submit('submit', 'Log Me In', css_class='btn btn-success'),
)
login.html
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
{% crispy form %}
{% endblock %}
Upon inspecting element in my browser, the col-lg-2 and col-lg-10 CSS classes are simply NOT being applied to the labels and fields respectively...
You should place all the helper logic under the __init__ method:
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(self, *args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'col-lg-2'
self.helper.field_class = 'col-lg-10'
self.helper.layout = Layout(
'username',
'password',
Submit('submit', 'Log Me In', css_class='btn btn-success'),
)