Django forms.form header field - django

I want to have a field type in forms.form that just takes in the text of a header to be displayed so the HTML would be something like:
This is header text for this section
Question
Question
Question
Another header
Question
Question
The idea is I'm declaring all the questions in the form on the fly using a model just for question pages, I need a header for some sections just to say what the sections are about. The inserting the questions on the fly is all working well so far it's just I need the last bit of display code to make it functional for what I need.
To give more information, this is my approach:
the admin creating the form creates questions in the admin interface
then adds the questions to a question form
when a user goes to the question page it renders the page with the questions using forms.form
The questions are declared using:
self.fields['id'] = forms.CharField(
max_length=100,
label=text, required=q.question.required)
What I want is to replace the above line with something like HeaderField which just has header text in a H1/2/3/4...etc container.
So the ideal syntax I want is
self.fields['id'] = forms.HeaderField(label=text, type=1)
Where type 1 is H1, 2 would be H2...etc

I ended up figuring out a solution on the spot using another answer. The solution was just mark the label as safe for HTML, then I can add HTML in directly and style it afterwards.
from django.utils.safestring import mark_safe
self.fields['id'.format(q.question.id)] = forms.CharField(
widget=forms.Textarea,
max_length=1000,
label=mark_safe(text), required=q.question.required)
After I do that I can add things like H1 or BR and style it directly. It's a little bit clunky but at least it works with the code that I already had.

Related

Django: a custom template tag to convert links inside of a TextField and change the hyperlink text

The scenario is that there are some dynamic texts on some templates, that will contain hyperlinks.
For this, I have a SiteDataKeyValue model, in which the dynamic texts for different parts of the template are inputted. This is the model:
class SiteDataKeyValue(models.Model):
key = models.CharField(
max_length=200, verbose_name="نام متن مورد نظر", unique=True
)
value = models.TextField(verbose_name="متن")
def __str__(self):
return self.key
A solution that I've found already, is Django urlize template tag. As mentioned in the docs, this tag converts texts like https://www.google.com to www.google.com, which is nice but not what I'd like to achieve. I want to be able to change the hyperlink text, so the output would be something like: Click Here!.
I searched for a bit, came across modules like bleach, which is a fine module, but I couldn't find the answer I was looking for (I skimmed through the docs and there was nothing about the hyperlink text).
Also I saw a comment somewhere telling that this could be achieved by writing a custom Django template tag, but although I tried to do this regarding the custom template filters docs, I didn't have a clue to how to achieve this.
I'm not asking for the code, although it would be really appreciated if you provide instructions for writing this custom template tag, or better, if you could point me to something like this that is already out there.
First of all you can extend urlize tag like the answer in this
or you can change the main code which you can find it in django.utils.html and override its url variable to change it.
But I think the best method is extending the urlize tag
like this:
{% text | urlize | change_a_text_filter:{{ dome_new_a_text }} %}
then you can scrape the text and use regex to find >sample-text</a> then you can change it to the argument that defines in your tag
from django import template
register = template.Library()
#register.simple_tag
def change_a_text_filter(format_string, arg):
# find the url that made in urlize with regex
# change it with arg
# return the result
I was on a completely wrong road to solve this problem. I was trying to urlize a link from TextField, but didn't consider the fact that I only needed to implement html code as Visit link.com! in the TextField, and then use safe template tag to render html directly as below:
{{ text.value|safe }}
So in this solution, there is no need to urlize, and of course there is no need to extend this tag neither.
NOTE: As commented by #rahimz (link to comment) I understand that there are safety concerns regarding safe tag, So I should emphasize that only me and a company-trusted admin will have access to admin panel and there is no worries that this admin will send malicious code through this TextField.

Illustrated texts in Django model

I am trying to make one Blog using Django 2.0 and I have already created a primitive one. It has a Post model which is as follows:
class Post(models.Model):
PriKey = models.CharField(max_length=255,primary_key=True)
Heading = models.CharField(max_length=100)
DateOfPost = models.DateField(default=datetime.date.today())
Content = models.TextField()
As it can be seen, the content area is only textual and as of now, I can't add any special style or pictures inside my content.
I thought of using HTML tags inside the text content but they are appearing unchanged when the web page is rendered.
So my question is, is there any way of storing pictures along with the text in the content field of the Post model? I want to make something like this
Is there any way of showing the pictures in their respective positions using Django model? If no, is there any other way of doing this?
Also, is there any way of storing HTML codes inside django models and render them as it is when the website is run?
You can store html tags inside the field.
while rendering, to template mark it as safe
{{ post.content|safe }}
This will render all the html tags.
But this is not a good way as it makes you vullerable to cross site scripting attacks
A better method is to use something like a ckeditor
It provides a RichTextField and RichTextUploading Field and using this you can upload pictures, videos, code snippets, style your text and a lot more inside one field.
There are many other optons, but I prefer ckeditor
Ckeditor is a cross platform editor, django-ckeditor is a library containing django implementation of ckeditor which gives you full backend and frontend combined
ckeditor
django-ckeditor
django-pagedown A django app that allows the easy addition of Stack Overflow's "PageDown" markdown editor to a django form field, whether in a custom app or the Django Admin
I think you should give it a try
Cheers :)

How to set attribute on widget in flask-wtf?

I am using a TextArea provided by Flask-WTF.
numbers = forms.TextField('Numbers', [forms.validators.Required()], widget=forms.widgets.TextArea())
I want to change cols of the resulting fields to say 80. How do I accomplish this. I don't want to do it in template and would like to do this in form.
Django provides:
name = forms.TextInput(attrs={'size': 10, 'title': 'Your name',})
I want something similar.
You can do it during output in your html
like: form.numbers(cols=20)
Oh, sorry did not notice that you mentioned template.
Update:
Actualy also had this problem, my solution was to extend Form class and add dictionary to form objects.
So all custom attributes go into that dictionary and used on output. This can be done with custom template macros or redefining render methods

Customizing Django.contrib.comments honeypot

I'm using Django's standard comment system and I would like to extend its anti-spam honeypot capability.
I thought of changing the default "name" and "id" of the field to something more alluring for spam-bots such as "website". I checked the html and this looks like this:
<p style="display:none;">
<label for="id_honeypot">Never send a human to do a machine's job</label>
<input type="text" name="honeypot" id="id_honeypot" />
</p>
Am I correct in thinking that changing the defaults of this element would boost its anti-spam capabilities? I tried modifying it in the django/contrib/comments/forms.py like this:
class CommentForm(CommentDetailsForm):
#use to be honeypot = forms.CharField(...
website = forms.CharField(required=False,
label=_('Never send a human to do a machines job')
def clean_honeypot(self):
"""Check that nothing's been entered into the honeypot."""
value = self.cleaned_data["website"]
if value:
raise forms.ValidationError(self.fields["website"].label)
return value
And this successfully changes the name and id in the html generated by django BUT then the whole mechanism stops working - I tried populating this invisible field, submitted and the comment was added.
I have a few other ideas as well, but first I'd really like to get this working - is it possible to modify the default honeypot name and id AND have it working like it should?
P.S I believe a more elegent way of doing this would be to extend django.contrib.comments and code the modification there instead of working on actual django code - what would be the best way of accomplishing this?
Given a bit more time to tinker around I found the answer to both of my questions:
In order to modify the standard honeypot or to create your own, you have to extend the CommentForm class by adding a clean_NAME_OF_HONEYPOT function as well as a NAME_OF_HONEYPOT variable both of which look similar to the standard ones and you also have to override the security_errors function to include the name of your new/modified honeypot in the dictionary.
The best way to do this is to create your custom comments app as described here: https://docs.djangoproject.com/en/dev/ref/contrib/comments/custom/ .
I hope this answer helps anyone else in my situation.

How to display more things in admin.StackedInline

I have Article model and a Comment model. Comment is created in admin.py as admin.StackedInline, and it has several fields, notably content and lastUpdate. For lastUpdate, i have specified as follows: lastUpdate = models.DateTimeField('last update', auto_now=True). Understandably, lastUpdate is not displayed when i try to add new comment (or edit old ones). However, i would like it to display for older comments if possible, as a read only thing. Is there anyway of accomplishing that?
Thanks a lot!
Jason
I guess if this http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields doesn't do what you want it to do, have a look at this: In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?