How to change label for User field, e.g. for username? I'm using CustomUser model that inherits AbstractUser, and I want to change label for some fields.
I try do next in CustomUser model, but it's not working. Any ideas?
class CustomUser(AbstractUser):
mobile = models.CharField(max_length=16)
address = models.CharField(max_length=100)
def __init__(self, *args, **kwargs):
super(CustomUser,self).__init__(*args, **kwargs)
self.username.__setattr__('label', 'Some text')
A Django model's fields are moved to Model._meta at class initialization, since Django 1.8, you can access them using the _meta API.
Also, label is an attribute of form fields, the equivalent for model fields is verbose_name.
This should work an Django 1.8
class CustomUser(AbstractUser):
mobile = models.CharField(max_length=16)
address = models.CharField(max_length=100)
def __init__(self, *args, **kwargs):
super(CustomUser,self).__init__(*args, **kwargs)
self._meta.get_field('username').verbose_name = 'Some text'
Before Django 1.8 you can use self._meta.get_field_by_name('username')[0] instead of self._meta.get_field('username').
Related
Imagine having a simple model like the one bellow:
from utils.validators import name_validator
class Customer(models.Model):
name = models.CharField(verbose_name="Customer Name", validators=[name_validator])
email = models.EmailField(verbose_name="Customer Email")
def __str__(self):
return self.name
Now if I explicitly define a filed on my serializer, both validators and verbose_name are lost. I can use label= and validatos= when defining the field on my serializer but I don't want to repeat myself. What if I have multiple serializer pointing to the same Model?
class CustomerSerilizer(serializers.ModelSerializer):
custom_field_name = serializers.CharField(source="name")
class Meta:
model = Customer
fields = "__all__"
Is there anyway to prevent this from happening?
I'm not sure if it's the perfect way of doing this or not, but I managed to achieve my desired behavior by writing a custom ModelSerializer which sets label and validators if they are not being passed when explicitly defining a field on the serializer.
class CustomModelSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
super(CustomModelSerializer, self).__init__(*args, **kwargs)
model = self.Meta.model
model_fields = [f.name for f in model._meta.get_fields()]
for field_name, field_instance in self.fields.items():
source_field = field_instance.source
if source_field in model_fields:
model_field = model._meta.get_field(source_field)
if "label" not in field_instance._kwargs:
field_instance.label = model_field.verbose_name
if "validators" not in field_instance._kwargs:
field_instance.validators.extend(model_field.validators)
I have table with some parameters like this:
class Education(models.Model):
title = models.CharField(default=None, max_length=100)
content = models.TextField(default=None)
In Django request from client maybe content field equals to NULL. So i want to when content parameter is NULL Django does not save it in database but does not show any errors.
Maybe already this field has data and in the Update request client just want to change title field.
In your form / serializer sets the content field as not required, so if the client doesn't want to update that field, it simply doesn't pass a value.
from django.forms import ModelForm
from .models import Education
class EducationForm(ModelForm):
class Meta:
model = Education
fields = ('title', 'content')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['content'].required = False
I found it, Just like this:
class EducationSerializer(serializers.ModelSerializer):
class Meta:
model = Education
fields = ['title', 'content')
extra_kwargs = {'content': {'required': False}}
Is it possible show an attribute of foreign key in add_form django?
For example:
#models.py
class Test(models.Model):
name = models.CharField(max_length=60, db_column='Name') # Field name made lowercase.
product=models.ForeignKey(Product, on_delete=models.DO_NOTHING)
class Product(models.Model):
id = models.AutoField(db_column='Id', primary_key=True)
description = models.CharField(max_length=60, db_column='Description')
#admin.py
class TestAdmin(admin.ModelAdmin):
fields = ['name','product','get_description']
readonly_fields = ['get_description']
def get_description(self):
return self.product.description
Naturally this code raise exception the ErrorFields in 'get_description'.
But, does exist a way to show the 'get_description' when I insert an entry of model Test?
Thanks
You can override the ModelAdmin.get_form and alter the form that it uses, to add a field of your choosing, filled with whatever you like. For example:
#admin.py
class TestAdmin(admin.ModelAdmin):
fields = ['name','product']
def get_form(self, request, obj=None, **kwargs):
if obj.product:
# self.form.base_fields is an OrderedDict(field_name=form.Field, ...)
self.form.base_fields['product_description'] = forms.CharField(required=False, initial=obj.product.description)
self.form.base_fields['product_description'].widget.attrs['readonly'] = True
return super(TestAdmin, self).get_form(request, obj, **kwargs)
That will add a readonly text input field as the last field in your "add" form. If you wanted it placed in a different spot witin the form, you'd have to work out some logic to rebuild self.form.base_fields as a new OrderedDict in exactly the order you'd like.
I'm attempting to display an image when editing a user on the admin panel, but I can't figure out how to add help text.
I'm using this Django Admin Show Image from Imagefield code, which works fine.
However the short_description attribute only names the image, and help_text doesn't seem to add an text below it.
How can I add help_text to this field like normal model fields?
EDIT:
I would like to have help_text on the image like the password field does in this screenshot:
Use a custom form if you don't want change a model:
from django import forms
class MyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['image'].help_text = 'My help text'
class Meta:
model = MyModel
exclude = ()
#admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
form = MyForm
# ...
It took me a while to figure out. If you've defined a custom field in your admin.py only and the field is not in your model. Use a custom ModelForm:
class SomeModelForm(forms.ModelForm):
# You don't need to define a custom form field or setup __init__()
class Meta:
model = SomeModel
help_texts = {'avatar': "User's avatar Image"}
exclude = ()
And in the admin.py:
class SomeModelAdmin(admin.ModelAdmin):
form = SomeModelForm
# ...
If you don't want to create a custom model form class :
class MyModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, change=False, **kwargs):
form = super().get_form(request, obj=obj, change=change, **kwargs)
form.base_fields["image"].help_text = "Some help text..."
return form
In my django application I have a model field called 'status'. In one of the forms to get data for this field, I only want to display a subset of all choices available in the model. Is there a way to remove a choice from a form? I need the removed choice in the database and the admin interface where I can select it.
status = models.CharField(STATUS_FIELD_NAME, choices=STATUS_CHOICES,
default=STATUS_DEFAULT,
max_length=3)
You could define the subset of choices in your form:
class YourForm(forms.ModelForm):
SUBSET_CHOICES = (
(YourModel.CHOICE_ONE, _('First choice')),
(YourModel.CHOICE_TWO, _('Second choice')),
)
class Meta:
model = YourModel
fields = ['choice', ]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['choice'].choices = self.SUBSET_CHOICES