Custom labels for UserProfileForm in Django - django

I'm using the UserProfileForm class under django.db to take the UserProfile model class and turn it into a form. Currently, the labels for the form elements are the column names of the underlying db table. I'm wondering if there is a way that I can customize the labels?
Thanks,
Tino

I think you mean a model form using django.forms.ModelForm. You can add a verbose name to your UserProfileModel, or you can use the label arg in your ModelForm like so:
>>> class ArticleForm(ModelForm):
... pub_date = DateField(label='Publication date')
...
... class Meta:
... model = Article
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#a-full-example
http://docs.djangoproject.com/en/dev/ref/forms/api/

Related

use `SplitArrayField` instead of `SimpleArrayField` in ModelForm

I have model with ArrayField and I want use ModelForm. Django by default use SimpleArrayField but I need SplitArrayField. I get my data from json and I use form only for validation and I don't need input widgets. (I use client side rendering)
class Profile(models.Model):
phone = ArrayField(CharField(max_length=20, validators=[some_validator]))
class ProfileForm(ModelForm):
class Meta:
model = Profile
form = ProfileForm(data={"phone":["555-5555","444-4444"]})
form.validate()
How I can use SplitArrayField in ModelForm?
I solve my problem with field_classes in Meta class:
class ProfileForm(ModelForm):
class Meta:
model = Profile
field_classes = {
'phone': SplitArrayField, # or any custom field
}
note:
SplitArrayField is not good enough for me so I create my own array form field
I think with pure django this is not possible at the moment. There is ticket which proposes the the possibility to use a SplitArrayField.
But you could use this package: django_postgres_extensions.
There you can use a SplitArrayField by defining the form_size parameter:
from django_postgres_extensions.models.fields import ArrayField
class Product(models.Model):
keywords = ArrayField(models.CharField(max_length=20), default=[], form_size=10, blank=True)

Custom columns in django_tables2

I've had a search around for this but haven't had much luck so looking for a bit of help. I'm trying to add some extra columns to a table defined by a model, using function definitions in the model. Here's what my code looks like now:
# models.py
class MyModel(models.Model):
my_field = models.TextField()
def my_function(self):
# Return some calculated value based on the entry
return my_value
# tables.py
class MyTable(tables.Table):
my_extra_column = tables.Column(....)
class Meta:
model = MyModel
# views.py
table = MyTable(MyModel.objects.all())
RequestConfig(request).configure(table)
return render(request, ....)
My question is can I access my_function in the entries passed to MyTable so I can show the result of my_function in the custom my_extra_column column? I assume I need to be using accessors, but I can't see how I can access the queryset data using this. Thanks!
I figured it out in the end, it was actually not too hard after all :)
So using my example above, in order to add a custom column using a function in the associated model you just use accessors ...
# models.py
class MyModel(models.Model):
my_field = models.TextField()
my_field_2 = models.IntegerField()
def my_function(self):
# Return some calculated value based on the entry
return my_value
# tables.py
class MyTable(tables.Table):
my_extra_column = tables.Column(accessor='my_function',
verbose_name='My calculated value')
class Meta:
fields = ['my_field', 'my_field_2', 'my_extra_column']
model = MyModel
The trouble comes if and when you want to be able to sort this data, because the function won't translate into any valid field in MyModel. So you could either disable sorting on this column using ordering=False or specify a set using order_by=('field', 'field2')

Selecting values to populate the combobox using Modelform

I want to get all the country names in a list so that i can set it it as source of a dropdown.
My modelform class looks like below
class UserExtForm(ModelForm):
countries = Countries.objects.values('countryname').filter(countryname__isnull = False)
class Meta:
model = UserExtras
fields=['phone','aboutme','countries']
I am trying to fill countries object with all the country names, but when the html form is displayed the dropdown is filled with text 'Countries object'. Please help me by pointing out what is here.
Thank you very much
in your models.py
from django.db import models
class Article(models.Model):
countries = models.CharField(max_length=200) //whatever
def __str__(self): # __unicode__ on Python 2
return self.countries
taken from the docs :
"It’s important to add str() methods to your models, not only for your own convenience when dealing with the interactive prompt, but also because objects’ representations are used throughout Django’s automatically-generated admin."

Django-import-export - export from model's functions?

For a Django model I'm using django-import-export package.
The manual says I can export fields that are not existing in the target model like so:
from import_export import fields
class BookResource(resources.ModelResource):
myfield = fields.Field(column_name='myfield')
class Meta:
model = Book
http://django-import-export.readthedocs.org/en/latest/getting_started.html
How do I export the output of functions from the model? e.g. Book.firstword()
Here's how you should do it (check this out https://django-import-export.readthedocs.org/en/latest/getting_started.html#advanced-data-manipulation):
from import_export import fields, resources
class BookResource(resources.ModelResource):
firstword = fields.Field()
def dehydrate_firstword(self, book):
return book.firstword()
class Meta:
model = Book
Update to answer OP comment
To return fields in a particular order, you can user the export_order Meta option (https://django-import-export.readthedocs.org/en/latest/api_resources.html?highlight=export_order#import_export.resources.ResourceOptions).
There is one more solution with less code, than that suggested by Serafeim:
from import_export import fields, resources
class BookResource(resources.ModelResource):
firstword = fields.Field(attribute='firstword')
class Meta:
model = Book
Just in case you need to get the full URL of the field and based on #Serafeim's solution
class CompanyModelResource(ModelResource):
def dehydrate_local_logo(self, company):
if company.local_logo and hasattr(company.local_logo, 'url'):
return company.local_logo.url
return company.local_logo
class Meta:
model = Company

Adding custom data to django model field

I'd like to add some info to a model field to use at form rendering time. My real model has about 15 values of varying field types (adding and removing as I dev), and it does almost everything I need, so I'd rather not create custom model fields for all of them.
I'd like to do something like this:
from django.db import models
class MyModel(models.Model):
cost = models.DecimalField(max_digits=5,
decimal_places=2,
custom_info= {'glyph': 'glyphicon glyphicon-usd' }
)
And then in my form template use that glyph much like I'd use a verbose_name or help_text.
Something I learned from a post just the other day. Will defining the custom information on the form instead of the model work?
When you define formfield_callback on a forms.ModelForm it will iterate over the form fields and you can manipulate them. This comes in handy when you need to add a css class to widgets and don't want to explicitly override the field. Now you only need to put formfield_callback = modify_form_field on any forms.ModelForm where you want the custom_info to show up.
from django.db import models
def add_glyphicons(model_field):
form_field = model_field.formfield()
if isinstance(model_field, models.IntegerField):
form_field.custom_info = {'glyph': 'glyphicon glyphicon-usd'}
elif isinstance(model_field, models.CharField):
form_field.custom_info = {'glyph': 'glyphicon glyphicon-yen'}
return form_field
class MyModel(models.Model):
formfield_callback = add_glyphicons
class Meta:
model = MyModel
class MyOtherModel(models.Model):
formfield_callback = add_glyphicons
class Meta:
model = MyOtherModel