How to limit fields in Form Django 2.2? - django

I got problem on limiting field shown in forms.ModelForm.
I Use Django 2.2
Currently I have
models.py
class MyModel(models.Model) :
user = models.ForeignKey(User, on_delete=models.CASCADE)
justchar = models.CharField(max_length=20, blank=True, null=True)
admins.py
class MyModelAdmin(admin.ModelAdmin) :
form=MyModelForm
admin.site.register(MyModel,MyModelAdmin)
form.py
class MyModelForm(forms.ModelForm) :
class Meta:
fields = ['user']
But the form still shows all fields.
I also tried with 'exclude', but got same results

You don't need a form for this. In fact, as the admin docs explicitly state, the fields attribute on a modelform is ignored in the admin.
Instead, just set fields directly on the admin class:
class MyModelAdmin(admin.ModelAdmin) :
fields = ['user']
admin.site.register(MyModel,MyModelAdmin)

Related

Making form fields - read only or disabled in DJANGO updateView

I have a model which I will update using an updateView generic class based function. How can I make specific fields as read only ?
example :
Models.py:
class Employee(models.Model):
emp_no = models.IntegerField( primary_key=True)
birth_date = models.DateField()
first_name = models.CharField(max_length=14)
last_name = models.CharField(max_length=16)
gender = models.CharField(max_length=1)
hire_date = models.DateField()
class Meta:
verbose_name = ('employee')
verbose_name_plural = ('employees')
# db_table = 'employees'
def __str__(self):
return "{} {}".format(self.first_name, self.last_name)
views.py :
class EmployeeUpdate(UpdateView):
model = Employee
fields = '__all__'
How can I make the first_name readonly inside a UpdateView ?
Note: I want to have the model(charfield) the same, But it should be read only inide an UpdateView.
When one wants to customize their forms the easiest way is to make a form class. A generic view is not really meant to provide all features a form class does, even though it makes life a little easy by generating the form for you by itself.
You want to be using a ModelForm [Django docs] and set disabled=True [Django docs] on your field:
from django import forms
class EmployeeUpdateForm(forms.ModelForm):
first_name = forms.CharField(max_length=14, disabled=True)
class Meta:
model = Employee
fields = '__all__'
Note: The disabled boolean argument, when set to True, disables a form field using the disabled HTML attribute so that it won’t be
editable by users. Even if a user tampers with the field’s value
submitted to the server, it will be ignored in favor of the value from
the form’s initial data.
Now in your view you simply want to set the form_class attribute:
class EmployeeUpdate(UpdateView):
model = Employee
form_class = EmployeeUpdateForm

Wagtail profile avatar into ImageRenditionField serializer

I want to serialize the profile avatar from Wagtail admin with ImageRenditionField.
Basing on the answer from the question I tried this:
# models.py
class User(AbstractUser):
def get_avatar(self):
return self.wagtail_userprofile.avatar
# serializers.py
class UserSerializer(serializers.ModelSerializer):
avatar = ImageRenditionField('width-190', source='get_avatar')
class Meta:
model = User
fields = ['id', 'username', 'first_name', 'last_name', 'avatar']
I got this:
Django Version: 3.1.4
Exception Type: AttributeError
Exception Value:
'ImageFieldFile' object has no attribute 'get_rendition'
How do I throw user avatar into ImageRenditionField?
The avatar field is a regular Django ImageField. It does not have get_rendition, it does not have any Wagtail rendition logic.
Take a look at wagtail.users.models.UserProfile.avatar
class UserProfile(models.Model):
...
avatar = models.ImageField(
verbose_name=_('profile picture'),
upload_to=upload_avatar_to,
blank=True,
)
and wagtail.images.models.AbstractImage.file (this is the base class of Wagtail Image).
class AbstractImage(CollectionMember, index.Indexed, models.Model):
...
file = models.ImageField(
verbose_name=_('file'), upload_to=get_upload_to, width_field='width', height_field='height'
)
Notice that avatar field is a regular Django ImageField. The Wagtail image is a model that stores additional image information and handles filters, focal points and renditions.
You can NOT use the Wagtail renditions in combination with avatar field, because avatar is a Django ImageField and not a Wagtail Image.
There are various thumbnail packages that provide thumbnail/scale functionality for Django ImageFields. Don't adjust the UserProfile.avatar field itself (customising Wagtail). Search for packages that play nice with plain ImageFields.
This question and answer might interest you.
you can do this
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = "__all__
class PersonSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
class Meta:
model = Person
fields = "__all__"
avatar = serializers.SerializerMethodField("get_avatar_display")
def get_avatar_display(self,info):
return info.wagtail_userprofile.avatar.url

Django Admin: readonly_fields not showing on admin. interface

This should be a pretty straight-forward thing, but it's not working as it should.
model
class Lesson(models.Model):
lesson_name = models.CharField(max_length=150, primary_key=True)
json_name = models.CharField(max_length=150, default="", null=True)
activity_type = models.CharField(max_length=20)
learning_language = models.CharField(max_length=50)
known_language = models.CharField(max_length=50)
admin
from .models import Lesson
class LessonAdmin(admin.ModelAdmin):
fields = ['lesson_name']
readonly_fields = ['json_name', 'activity_type', 'learning_language', 'known_language']
admin.site.register(Lesson, LessonAdmin)
But, when I log into the admin site, the fields specified in readonly_fields don't show up at all. I've also tried including the field names in a tuple instead of a list (as the documentation specifies), but that gives me an error even.
The actual fields displayed are only set in list_display, fields and fieldsets. readonly_fields just tells the admin, of those that it would display, which to display as read-only. So just add the same fields to your fields list as well. It's duplication, which is annoying, but more explicit.
class LessonAdmin(admin.ModelAdmin):
fields = ['lesson_name', 'json_name', 'activity_type', 'learning_language', 'known_language']
readonly_fields = ['json_name', 'activity_type', 'learning_language', 'known_language']
And it doesn't matter if you use a tuple or a list, the django admin accepts both.

Extending User fields in UserCreationForm

I am trying to add some custom fields to a user, and extend the UserCreationForm so that I can add these fields when the user is created. I am following the docs but when I try to load the page to create a user I get an error: Unknown field(s) (username) specified for Customer.
The docs that I am following: Custom User and Auth Forms
models.py
class User(AbstractUser):
is_restaurant = models.BooleanField(default=False)
is_customer = models.BooleanField(default=False)
class Customer(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
address = models.CharField(max_length=200)
def __str__(self):
return self.user.get_full_name()
forms.py
class CustomerSignUpForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = Customer
fields = UserCreationForm.Meta.fields + ('address',)
I understand that username is not part of the Customer class, but the docs appear to be doing the same thing...
The doc says:
If your custom user model is a simple subclass of AbstractUser, then
you can extend these forms in this manner...
In other words this will work only in case you want to add to the form is_restaurant or is_customer fields:
class CustomerSignUpForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = User
fields = UserCreationForm.Meta.fields + ('is_restaurant',)
But in your case Customer is not subclass of AbstractUser, since this method is not working for you. As a workaround you can try to work with two separate forms in the same time as suggested in this answer.

Django 1.9 forms include is not showing in admin

Im trying to change the view of admin though I try to modify admin with the help of forms, I dont see any changes and end up with all the fields
My model consisting primarily of email and name
class SignUp(models.Model):
email = models.EmailField()
full_name = models.CharField('name',max_length=120, blank=True, null=True,)
timestamp = models.DateTimeField('time',auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __unicode__(self): #Python 3.3 is __str__
return self.email
My form
class SignUpForm(forms.ModelForm):
class META:
model= SignUp
fields=['email']
Im trying to add the form in admin so that only email is displayed
My admin, I'm trying to include only email field
class SignUpAdmin(admin.ModelAdmin):
list_display = ['full_name', 'timestamp', 'updated']
form = SignUpForm
admin.site.register(SignUp, SignUpAdmin)
But I end up with both email and name displayed. I only wanted email to be shown in admin page
Any help is much appriciated......Thanks in advance
I'm assuming the indentation on meta is a copy/paste error in your question, but that needs to be indented in your class, but also, it shouldn't all be capitalised
class SignUpForm(forms.ModelForm):
class Meta:
model= SignUp
fields=['email']