Wagtail profile avatar into ImageRenditionField serializer - django

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

Related

Django - Remove currently displayed image link In An Image Edit Form

I am using Django 2.2 for a project, I want to remove the currently displayed image link from the user update form as shown in the image below, how do I do this?
image
forms.py
from .models import Profile
class CreateUserForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = ['username', 'email', 'password1', 'password2']
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email']
help_texts = {
'username': None,
}
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['profile_pic']
You can try to change ImageField to FileInput using widgets. I use Django version 4.1.1 and it works for me.
# forms.py
class ProfileUpdateForm(forms.ModelForm):
profile_pic = forms.ImageField(widget=forms.FileInput)
class Meta:
...

How to limit fields in Form Django 2.2?

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)

create a user in Django 2.1 that is associated with an existing model

In my models.py file I have the following code ->
from django.db import models
class Blogger(models.Model):
username = models.CharField(max_length=20)
email = models.EmailField()
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
password = models.CharField(max_length=30, default='')
I want to associate the Blogger model with a User and create the User upon form submission. Here is the forms.py file ->
from django import forms
from blog.models import Blogger
class BloggerForm(models.ModelForm):
class Meta:
model = Blogger
fields = ['username', 'email', 'first_name', 'last_name', 'password']
And here is the views.py ->
class BlogView(FormView):
template_name = 'blogform.html'
form_class = BloggerForm
success_url = 'blog/'
How do I create a new user on the submission of this form ?
All fields in blogger already exists in User model, actually you don't need this Blogger model at all, just use the User model directly.
There's a couple ways you can do this but basically the general 2 answers are:
Toss/copy Django's user model and make your own (hard)
Extend the user model by making a new model, and relating it to the user model (easy)
I usually choose option #2 because then you don't have to reconfig the auth system. This is a good tutorial on how to do it: simpleisbetterthancomplex

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']

Access from django admin list_display, a value from a One-To-One table

Given a one-to-one extension a model, such as the Django User model:
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile', unique=True)
avatar = models.ImageField(_('Avatar'))
foo = models.CharField(max_length=100, verbose_name="xxx")
How can I display that in the admin?
class UserAdmin(admin.ModelAdmin):
list_display = ('email', 'profile__foo' <--NOT WORKING )
A near match question is Django Admin: How to display value of fields with list_display from two models which are in oneToOne relation?
The general method would be:
class UseAdmin(admin.ModelAdmin):
list_display = ('email', 'profile_foo')
def profile_foo(self, x):
return x.profile.foo
profile_foo.short_description = 'foo'
x here is the object of the model you are displaying