Crisp keeps on throwing error 'BoundWidget' object has no attribute 'field' - html

Using crisp tags for creating a user registration form in Django application.
Here are codes in few my files to help:
Settings.py
INSTALLED_APPS = [
'blog.apps.BlogConfig',
'users.apps.UsersConfig',
'crispy_forms',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
HTML File
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
{% csrf_token %}
{{form.first_name|crispy}}
{{form.last_name|crispy}}
{{form.username|crispy}}
{{form.email}}
{{form.password1|crispy}}
{{form.password2|crispy}}
other statements are CSS and HTML which i feel are not the concerned part for this question. However I will like to add that I do have done some styling for the Input tags (the form input fields).
Form.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserRegisterForm(UserCreationForm):
first_name = forms.CharField()
last_name = forms.CharField()
email = forms.EmailField()
username = forms.TextInput(attrs={'placeholder': 'Username'})
class Meta:
model = User
fields = ['first_name','last_name', 'username', 'email', 'password1', 'password2']
I have added the screenshot of errors thrown when webpage is requested:
The other part of the question or the reason I am using crisp is I need to authenticate input information and want to display warnings accordingly in short i want to customize the wrong input warnings for the registration form a referral to that kind of article is appreciated as i am unable to find one.

I had the same issue ,try this , it worked for me:
in the html file use:
{{form.first_name| as_crispy_field }}

In HTML file, just put either this{{form|crispy}} or {{form.fieldname|as_crispy_field}}

Related

How to edit html content in Django forms?

Because I am not from English Naive country.
Default html content from Django form, is not suitable for my country.
Could someone tell me how to edit html content in forms.py?
I just want to keep English variable for later SQL column settings, but change html content in form.
in forms.py
class DjUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = DjUser
fields = ('username', 'email', 'password')
in html
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ user_form.as_p }}
<input type="submit" value="註冊">
</form>
It showed all English content in html, like Username, Email Address etc..
The thing I needed is 使用者名稱, 電子信箱 etc.. The html contents I want to edit:
You can use attr for styling and naming you're form fields, it will go something like this:
class DjUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={
'class': 'my-class',
'placeholder': '使用者名稱, 電子信箱',
}))
also you will perhaps need to do some localization for you're application.

Django,html template,for loop not working as expected

I am trying to apply a for loop to the following html (in a Django project) such that the 'Name' and the 'Comments' field are caused to repeat on the html view.
When I insert the templating code, that is:
{% for c in comments %}
{% endfor %}
on either side of the content i want to repeat, it simply makes the name and comments disappear altogether and does not have the desired result.
The relevant parts of the file are below:
index.html (the main html page)
{% load static %}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="{% static 'guestbook/styles.css' %}">
</head>
<body>
<h1>The world's guestbook</h1>
<p>Sign the guestbook</p>
{% for c in comments %}
<h2>Name</h2>
<p>This the message that the user leaves.</p>
{% endfor %}
</body>
</html>
views.py (in the guestbook app)
from django.shortcuts import render
from .models import Comment
# Create your views here.
def index(request):
comments = Comment.objects.order_by('-date_added')
context ={'comments': comments}
#name=Name.objects.order_by('-date_added')
return render(request,'guestbook/index.html')
def sign(request):
return render(request,'guestbook/sign.html')
models.py file
from django.db import models
from django.utils import timezone
# Create your models here.
class Comment(models.Model):
name=models.CharField(max_length=20)
comment=models.TextField()
date_added=models.DateTimeField(default=timezone.now)
def __str__(self):
return self.name
I am working off a tutorial in which this is the recommended code and the desired result is as expected - I notice my html template does not have div tags and wonder if that could be an issue? If so, how can it be resolved?
You need to pass that context:
def index(request):
comments = Comment.objects.order_by('-date_added')
context ={'comments': comments}
return render(request,'guestbook/index.html', context=context)
^^^^^^^^^^^^^^^
From documentation of render:
Context: A dictionary of values to add to the template context. By default, this is an empty dictionary. If a value in the dictionary is
callable, the view will call it just before rendering the template.
Meaning, the values inside dictionary which is being used with known argument context of render function, these values will be sent to the template. Then you can access those values through {{ key }} of the dictionary(which is sent as context) in html template, or your case {{ comments }}. More information can be found regarding context in this SO Answer.

DJANGO template tags in plain text not displaying

I am making an app that displays questions. The question model has a text field and an image field. Each question has a template that is stored in my database in the text field. My problem is when I want to access images from the model, template tags are displayed as text and not rendering. My code:
# question model
class Question(models.Model):
question_text = models.TextField()
question_image = models.FileField(upload_to='static/images/questions', blank=true)
# question view
def question(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'questiontemplate.html', {'question': question})
# template
{% extends 'base.html %}
{% load static %}
{% autoscape off %}
{{ question.question_text }}
{% endautoscape %}
# in my database:
question.question_text = '<p> some html
{{ question.question_image.url }}
some html </p>'
question.question_image = 'image.png'
This works fine and renders the html perfectly except the template tag is not rendered and does not not give the image url
I want this to be the output:
Some html
static/images/questions/image.png
some html
But instead this is the output:
some html
{{ question.question_image.url }}
some html
Any suggestions to how the template tags could be render from the database text would be much appreciated.
Thanks for reading
Django doesn't know that the content in your model field is itself a model. The template can't know that. The only way to make this work is to treat that field itself as a template, and render it manually.
You could do that with a method on the model:
from django.template import Template, Context
class Question(models.Model):
...
def render_question(self):
template = Template(self.question_text)
context = Context({'question': self})
rendered = template.render(context)
return mark_safe(rendered)
Now you can call it in your template:
{{ question.render_question }}

Unable to link blog post to its content page in Wagtail

I'm having a problem creating a link of a Blog Post to its own content page in wagtail. In my models I have two page classes, BlogPage and IndexPage. My BlogPage class is used to create the blog post, and IndexPage class is used to display a list of blog posts.
Please see models below:
from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.wagtailcore.models import Page, Orderable
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, InlinePanel
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtailsearch import index
class IndexPage(Page):
intro = RichTextField(blank=True)
def child_pages(self):
return BlogPage.objects.live()
content_panels = Page.content_panels + [
FieldPanel('intro', classname='full'),
]
subpage_types = ['blog.BlogPage']
class BlogPage(Page):
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
search_fields = Page.search_fields + (
index.SearchField('intro'),
index.SearchField('body'),
)
content_panels = Page.content_panels + [
FieldPanel('date'),
FieldPanel('intro'),
FieldPanel('body', classname="full")
]
My challenge is that I can't figure out how to link the blog post on the Index Page to its own page. Do I need to create a separate page model and html template to achieve this? or what could be the best approach to solve this problem?
You can create an include template (it doesn't need a model) - let's name it truncated_blog_post.html - which you can then invoke in your index_page.html template. This would be the recommended approach because using a include template for a post gives the possibility to use it anywhere you need to display a list of (truncated usually) posts: when you want the posts under a certain tag, for example.
truncated_blog_post.html
{% load wagtailcore_tags %}
<article>
<h2>{{ blog.title }}</h2>
<p>{{ blog.date }}</p>
<p>{{ blog.body|truncatewords:40 }}</p>
</article>
Using the pageurl tag from wagtailcore_tags you get the relative URL of that blog post. Obviously, if you don't want to create a include template for a truncated post, you can put the article code from blog_post.html directly in the for loop in the index_page.html template.
And your index_page.html template:
....
{% for blog in blogs %}
{% include "path/to/includes/truncated_blog_post.html" %}
{% empty %}
No posts found
{% endfor %}
....
For this to work you have to modify the IndexPage model:
class IndexPage(Page):
intro = RichTextField(blank=True)
#property
def blogs(self):
blogs = BlogPage.objects.live()
return blogs
def get_context(self, request):
# Get blogs
blogs = self.blogs
# Update template context
context = super(IndexPage, self).get_context(request)
context['blogs'] = blogs
return context
content_panels = Page.content_panels + [
FieldPanel('intro', classname='full'),
]
subpage_types = ['blog.BlogPage']

Django 'ManagementForm data is missing or has been tampered with' when saving modelForms with foreign key link

I am rather new to Django so this may be an easy question. I have 2 modelForms where there is a ForeignKey to another. My main goal is to save Indicators with a link to Disease (FK), such that for a particular disease, you can have multiple indicators.
With the code below, I get an error when I hit submit that says 'ManagementForm data is missing or has been tampered with'. Also, the code in views.py does not seem to be validating at the 3rd 'if' statement where there is a return HttpResponseRedirect. However, when I check my database, the values from the form have been written. Any ideas on why the error has been raised? and how to fix it?
My code is below:
models.py
#Table for Disease
class Disease(models.Model):
disease = models.CharField(max_length=300)
#Tables for Indicators
class Indicator(models.Model):
relevantdisease = models.ForeignKey(Disease)
indicator = models.CharField(max_length=300)
forms.py
class DiseaseForm(forms.ModelForm):
class Meta:
model = Disease
class IndicatorForm(forms.ModelForm):
class Meta:
model = Indicator
DiseaseFormSet = inlineformset_factory(Disease,
Indicator,
can_delete=False,
form=DiseaseForm)
views.py
def drui(request):
if request.method == "POST":
indicatorForm = IndicatorForm(request.POST)
if indicatorForm.is_valid():
new_indicator = indicatorForm.save()
diseaseInlineFormSet = DiseaseFormSet(request.POST, request.FILES, instance=new_indicator)
if diseaseInlineFormSet.is_valid():
diseaseInlineFormset.save()
return HttpResponseRedirect('some_url.html')
else:
indicatorForm = IndicatorForm()
diseaseInlineFormSet = DiseaseFormSet()
return render_to_response("drui.html", {'indicatorForm': indicatorForm, 'diseaseInlineFormSet': diseaseInlineFormSet},context_instance=RequestContext(request))
template.html
<form class="disease_form" action="{% url drui %}" method="post">{% csrf_token %}
{{ indicatorForm.as_table }}
<input type="submit" name="submit" value="Submit" class="button">
</form>
You have neither diseaseFormSet nor diseaseFormSet's management form in your template, yet you try to instantiate the formset. Formsets require the hidden management form which tells django how many forms are in the set.
Insert this into your HTML
{{ diseaseFormSet.as_table }}
{{ diseaseFormSet.management_form }}