Django如何获取用户组列表并作为模型字段的可选选项?
Got it, let's fix this so your editor field automatically pulls options from Django's system user groups instead of hardcoding them. Here are two reliable approaches:
Approach 1: Dynamic Choices for the Model Field
Django lets you pass a callable function to the choices parameter of a model field (works in Django 3.0+; for older versions, you can use a similar approach with a property or override the field's choices method). This function generates the choice list on the fly every time it's needed, so new groups will show up automatically.
Update your model code like this:
from django.db import models from django.contrib.auth.models import Group def get_group_choices(): # Fetch all user groups from the database, return (group_name, group_name) tuples group_tuples = Group.objects.values_list('name', 'name') # Prepend the default "Undefined" option to the list return [('0', 'Undefined')] + list(group_tuples) class Questions(models.Model): editor = models.CharField( max_length=350, default='0', # Changed to string to match the choice key (CharField expects string values) choices=get_group_choices, # Pass the function itself (no parentheses!) verbose_name='Responsibility' ) # Add your other model fields here...
Key Notes:
- The
get_group_choicesfunction pulls fresh group data every time it's called, so you don't have to update code when new groups are created. - When running
makemigrations, Django won't store dynamic group data in the migration file (since choices are generated at runtime) — which is exactly what we want for a dynamic list.
Approach 2: Customize the Form (Perfect for Django Admin)
If you only need dynamic options in the Django admin (or specific custom forms), you can override the form field to use a ModelChoiceField that directly queries the Group model. This keeps your model clean while giving you form-specific control.
In your admin.py:
from django.contrib import admin from .models import Questions from django.contrib.auth.models import Group class QuestionsAdmin(admin.ModelAdmin): def formfield_for_dbfield(self, db_field, **kwargs): if db_field.name == 'editor': # Replace the static choice list with a dynamic group dropdown field = super().formfield_for_dbfield(db_field, **kwargs) field.queryset = Group.objects.all() field.empty_label = 'Undefined' # Set the default empty option return field return super().formfield_for_dbfield(db_field, **kwargs) admin.site.register(Questions, QuestionsAdmin)
Why This Works:
- Your model still uses a
CharFieldto store group names, but the admin form replaces the static dropdown with one that loads all current groups. - New groups will appear in the admin dropdown automatically, no extra code changes needed.
Quick Bonus Tips
- Django's
Groupmodel enforces unique group names, so you won't have duplicate options in your dropdown. - If you use this field in non-admin forms, you can apply the same
ModelChoiceFieldlogic to your custom form classes for consistent dynamic behavior.
内容的提问来源于stack exchange,提问作者Mohammad

