How to apply Filter_horizontal widget in UpdateView, CreateView? Not in the administrative model.
Django 4
filter_horizontal widget in CreateView, UpdateView
Related
I'm trying to use CheckboxSelectMultiple in a form, instead of the SelectMultiple default. I tried two different ways to make it display as checkboxes, but they both display the default SelectMultiple on my local webpage. Everything else renders correctly ( {{ form.as_table }} ). Would someone point me in the right direction? Thanks,
Django version 3.0.2
Python 3.6.9
models.py
class MyModel(models.Model):
m2m = models.ManyToManyField('OtherModel', blank=True)
[...]
forms.py
from django.forms import ModelForm
from myapp.models import MyModel
class MyModelModelForm(ModelForm):
[...]
# I tried this...
m2m = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple)
class Meta:
model = MyModel
fields = '__all__'
# or this...
widgets = {
'm2m': forms.CheckboxSelectMultiple,
}
views.py
from django.views.generic.edit import CreateView
from myapp.models import MyModel
class MyModelCreate(CreateView):
model = MyModel
fields = '__all__'
template_name = 'MyApp/mymodel_form.html'
You did not use the form you constructed. You simply constructed a ModelForm, and then let the CreateView create another ModelForm since you did not specify a form_class [Django-doc].
You can thus update the CreateView, and work with:
from django.views.generic.edit import CreateView
from myapp.models import MyModel
from myapp.forms import MyModelModelForm
class MyModelCreate(CreateView):
model = MyModel
form_class = MyModelModelForm
template_name = 'MyApp/mymodel_form.html'
I'm trying to create two different types of users in Django using AbstractUser. I've created two models that inherit from my AbstractUser model.
How do I update the UserCreationForm so that it has a field for user type?
Just override the built-in UserCreationForm and adjust the fields as necessary.
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = UserCreationForm.Meta.fields + ('type',)
I am creating a custom field in my serializers file
new_field= serializers.SerializerMethodField(read_only=True)
def get_new_field(self,obj):
# do something
Is there a way I can display this field in the django admin panel?
You can customise your django admin panel like this:
class MyModelAdmin(models.ModelAdmin):
list_display = ('field1', 'field2', 'new_field')
list_editable = ('field1')
def new_field(self, obj):
return obj.new_field.name
admin.site.register(MyModel,MyModelAdmin)
I'm creating models, where each model should be related with a user, like this:
class Item(models.Model):
user = models.ForeignKey(User)
But then in the Django Admin, for an Item, it shows a select field with all the users listed by their usernames. In addition to their usernames, I also need to display each user's first_name and last_name.
How can all three fields be displayed together within that select list in the Django Admin interface?
You need to create custom Form for this and set form attribute in your ModelAdmin.
In that Form you will need to override form field type of user field on model to custom ModelChoiceField.
ModelChoiceField has a method called label_from_instance, you need to override that to get full name.
Example code
######################################
## models.py ##
######################################
from django.db import models
from django.contrib.auth.models import User
class Item(models.Model):
user = models.ForeignKey(User)
name = models.CharField("name", max_length=60)
def __unicode__(self):
return self.name
######################################
## forms.py ##
######################################
from django import forms
from django.contrib.auth.models import User
from .models import Item
class CustomUserChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.get_full_name()
class ItemForm(forms.ModelForm):
user = CustomUserChoiceField(queryset=User.objects.all())
class Meta:
model = Item
######################################
## admin.py ##
######################################
from django.contrib import admin
from .models import Item
from .forms import ItemForm
class ItemAdmin(admin.ModelAdmin):
form = ItemForm
admin.site.register(Item, ItemAdmin)
Source Code Reference
https://github.com/django/django/blob/1.4.5/django/forms/models.py#L948
Related Questions
Django admin - change ForeignKey display text
Django forms: how to dynamically create ModelChoiceField labels
Change Django ModelChoiceField to show users' full names rather
than usernames
Django show get_full_name() instead or username in model form
django: customizing display of ModelMultipleChoiceField
django how to display users full name in FilteredSelectMultiple
Django ModelChoiceField drop down box custom population
customize select in django admin
Use method other than unicode in ModelChoiceField Django
Django uses unicode(obj) (or the related function, str(obj)) in a number of places. Most notably, to display an object in the Django admin site and as the value inserted into a template when it displays an object.
Please see __unicode__ from https://docs.djangoproject.com/en/dev/ref/models/instances/
You can change __unicode__ method of User class. See below example codes.
from django.db import models
from django.contrib.auth.models import User
def myunicode(self):
return self.get_full_name()
# Create your models here.
class Item(models.Model):
User.__unicode__ = myunicode
user = models.ForeignKey(User)
name = models.CharField("name", max_length=60)
def __unicode__(self):
return self.name
My site makes use of Django's User Authentication User model and a custom UserProfile model to store some additional data (birthday, etc.). Is there a way to create a view in Django admin that weaves together fields from both the User and UserProfile models?
I suspect that this code snippet is not even close, but maybe it will help illustrate what I'm trying to do:
from django.contrib import admin
from django.contrib.auth.models import User
from userprofile.models import UserProfile
class UserProfileAdmin(admin.ModelAdmin):
list_display = ('name', 'gender', 'User.email') #user.email creates the error - tried some variations here, but no luck.
admin.site.register(UserProfile, UserProfileAdmin)
Error message:
ImproperlyConfigured: UserProfileAdmin.list_display[2], 'User.email' is not a callable or an attribute of 'UserProfileAdmin' or found in the model 'UserProfile'.
Ultimately, I'm trying to create an admin view that has first & last name from UserProfile and email from User.
for displaying user email you need to have a method on UserProfile or UserProfileAdmin that returns the email
on UserProfile
def user_email(self):
return self.user.email
or on UserProfileAdmin
def user_email(self, instance):
return instance.user.email
then change your list_display to
list_display = ('name', 'gender', 'user_email')
Related docs: ModelAdmin.list_display
You could try using InlineModelAdmin to display both User and UserPofile forms in a admin view.
To display user profile information in change list you can create a new method that delegates the values from UserProfile to User model.
For example this should work more or less :)
from django.contrib import admin
from django.contrib.auth.models import User
from my_models import UserProfile
class UserProfileInline(admin.StackedInline):
model = UserProfile
fk_name = 'user'
class UserAdmin(admin.ModelAdmin):
list_display = ['get_userprofile_name', 'email']
list_select_related = True
inlines = [
UserProfileInline,
]
def get_userprofile_name(self, instance):
# instance is User instance
return instance.get_profile().name
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Using Ashoks top answer i made snippet that simplifies this process for large number of fields
class ColumnViewer(object):
pass
column_list = ('name', 'surname', )
for col in column_list:
setattr(ColumnViewer, col, lambda s,i : getattr(i, col))
#admin.register(UserProfile)
class UserProfileAdmin(admin.ModelAdmin, ColumnViewer):
list_display = column_list