How to set attribute on widget in flask-wtf? - flask

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

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.

Allow additional attributes, like placeholder text or icon, on model

I use modelforms in several places in my app, and have written custom bootstrap form rendering. It's working well, but I'd like to be able to add addon_before to some of my fields (example, for twitter_username i'd set addon_before='https://twitter.com/. I'd also like to specify icon classes and placeholder text for some fields.
I know I can do this in the form rendering, but I render the same fields in several different forms, and I dont want to repeat the form settings. using the twitter_username example, is there a way to globally set wherever that field is used in a modelform, to include a set of attributes and values
{'addon_before': 'https://twitter.com/', 'placeholder': '#username', 'icon': 'fa-twitter'}
Would love any suggestions!

Using jquery autocomplete Django form

I am using jquery autocomplete with my generic views on Django. I am getting the list via AJAX, but there is one problem. When the user get the category he wants, he will select that value. Thus, if I append the value on that field $("#id_category").val(ui.item.value); it will show the pk on that field instead of value, so if I append $("#id_category").val(ui.item.label); django will complain it should be the instance. Django is completely right. How to make this work?
Edit:
I have made id_category hidden field and added category_display to append the text value. It is working. But while editing the category_display would be empty. Again I am using generic view. How to solve this one on the edit?
I had similar issue and I suggest you to think about question: 'What will happen if user enters not valid category name(category with this name doesn`t exist)?'
if you need to accept entered value and add new category, you have to make clean_category method in form:
def clean_category(self):
name = self.data['category']
return Category.objects.get_or_create(name=name)[0]
and display ui.item.label for user
if new category isn`t acceptable you can raise error in clean_category method or use something like select2(http://ivaynberg.github.io/select2/) for your field. I choose second variant.

In Django, how to validate a (multiple) cholice field when the choices are added by Javascript?

I have a ChoiceField where the choices are not known at the time the HTML is rendered; they are defined dynamically by the user and added to the form through Javascript, but the validation naturally fails since the selected option is not in the choices attribute (which is just an empty list). I have tried setting the field to a CharField, but then the validator just gets a string value that needs to be converted into a list before it van be used. Ah, and I'd like to avoid subclassing the field class as it's just for one occasion.
I hope this is clear. Any ideas?
Don't subclass the field class but override the clean_<yourfield> method in your Form class. See the docs here.

Database localization in Django

I am using .mo files for localization in Django.
Also, in my database, I store some translated text in different fields, such as:
name_en, name_es, name_de (they are all columns in each row).
What will be the best method to choose the correct field inside a template?
i.e.:
{{ name.some_method }} will generate the correct translation based on the current localization.
Thanks,
Meit
You should look at http://goodcode.io/articles/django-multilanguage/ Here’s a simple solution that may fit your use case and is easy to implement and understand.
You should look at Django Transmeta, it work the same way as what you've done (DB fields with language code) but it's a more complete solution. It already deal with the template stuff, etc.
You can check Model Internationalization and Django Packages for more info and ideas in this domain.
I can see two method for doing this, one in your view and the other one is in the template...
In view:
Probably you keep the user language information somewhere so,
user_lang = 'es'
obj = Somemodel.objects.get(pk=123434)
obj.local_name = getattr(obj, 'name_%s'%user_lang)
So, you keep local translation in a specific variable of the instance and in your template you can use is as:
{{obj.local_name}}
But that might be costly if you wish to pass the template a queryset instead of a single instance. For a such usege you have to evaluate that value for each object in your queryset.
In template:
That is a more complex way of solving the porblem in the template...
Define a template tag and pass object_id, and local language information and get the translated text using a similar getattr function. But in that point, if you wish to use this for more than one model, you probably have to pass a content type information for your template tag too, such as:
{% get_translation <object_id> <content_type_id> <local_language> %}
And in your template tag function, do something like:
from django.contrib.contenttypes.models import ContentType
....
cont_obj = Content_type.objects.get_for_id(<cotent_type_id>) #get the related model
obj = cont_obj.get_object_for_this_type(pk=<object_id>) # get your object
return getattr(obj, 'name_%s'%<local_language>)