Django中如何将多选用户邮箱以逗号分隔存入Model B字段?
Hey there! The issue with your current code is that a plain TextField only gives you a text input box—it doesn’t provide an interface to select existing User emails, let alone multiple ones. Let’s fix this with two approaches: one that meets your comma-separated storage requirement, and a better practice alternative for database normalization.
Approach 1: Comma-Separated Emails (As Requested)
We’ll use a custom form to add a multi-select dropdown for User emails, then handle converting selections to a comma-separated string on save.
Step 1: Correct Model B Definition
First, fix your model with properly defined fields:
from django.db import models from django.contrib.auth.models import User # Assuming you're using Django's default User model class B(models.Model): organization = models.CharField(max_length=200, blank=False, null=True) designation = models.CharField(max_length=200) # Lowercase field names per Django conventions share_knowledge_with = models.CharField(max_length=200) abc = models.CharField(max_length=200) # Adjust field type if needed (e.g., TextField) manager = models.CharField(max_length=200) # Consider a ForeignKey to User if manager is a system user emails_for_help = models.TextField(blank=True) # Will store comma-separated emails
Step 2: Create a Custom Model Form
This form adds a multi-select field for User emails and handles converting selections to the comma-separated format:
from django import forms from .models import B, User class BForm(forms.ModelForm): # Multi-select field populated with all User emails selected_emails = forms.MultipleChoiceField( choices=[(user.email, user.email) for user in User.objects.all()], widget=forms.SelectMultiple(attrs={'class': 'form-control'}), required=False, label="Emails for Help" ) class Meta: model = B fields = ['organization', 'designation', 'share_knowledge_with', 'abc', 'manager'] exclude = ['emails_for_help'] # We'll handle this via selected_emails def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Pre-fill selections when editing an existing instance if self.instance.pk: saved_emails = self.instance.emails_for_help.split(',') if self.instance.emails_for_help else [] self.fields['selected_emails'].initial = saved_emails def save(self, commit=True): instance = super().save(commit=False) # Join selected emails into a comma-separated string selected_emails = self.cleaned_data.get('selected_emails', []) instance.emails_for_help = ','.join(selected_emails) if commit: instance.save() return instance
Step 3: Use the Form in Your Views
Replace the default model form with BForm in your create/update views:
from django.views.generic.edit import CreateView, UpdateView from .models import B from .forms import BForm class BCreateView(CreateView): model = B form_class = BForm success_url = '/path/to/success/' # Replace with your actual success URL class BUpdateView(UpdateView): model = B form_class = BForm success_url = '/path/to/success/'
Approach 2: Better Practice (ManyToManyField)
Storing comma-separated values is not database-normalized and makes querying/updating harder. If you can adjust your requirements, use a ManyToManyField to link directly to User models:
class B(models.Model): organization = models.CharField(max_length=200, blank=False, null=True) designation = models.CharField(max_length=200) share_knowledge_with = models.CharField(max_length=200) abc = models.CharField(max_length=200) manager = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='managed_b_records') emails_for_help = models.ManyToManyField(User, related_name='help_requests')
Display Comma-Separated Emails in Templates
To show emails as a comma-separated string in your templates:
{{ object.emails_for_help.values_list('email', flat=True)|join:', ' }}
Why Your Original Code Failed
A TextField only renders a plain text input—there’s no built-in way to select existing User emails. The custom form adds the necessary UI and logic to map selections to the comma-separated format your model expects.
内容的提问来源于stack exchange,提问作者conf

