Home > database >  How to modify values in m2m field in form? (Django)
How to modify values in m2m field in form? (Django)

Time:12-24

I have 2 models in my models.py. They are Doctor and Specialty:

class Doctor(models.Model):
    name = CharField(max_length=255)
    specialties = ManyToManyField('Specialty', related_name='doctors')
    mc_id = CharField(max_length=255, unique=True)

class Specialty(models.Model):
    name = CharField(max_length=255)
    mc_id = CharField(max_length=255, unique=True)

    def __str__(self):
        return self.name

When i'm creating new Doctor instance via admin interface (change_form.html template) I see my Doctor model fields, which I should fill with data. Among these fields there is a field specialties ("Cпециальности"), which is m2m field and contains names (as I set __str__(self) method in Specialty model to return self.name) for specialties which were previously added to Specialty model (see a screen).

All I want is to see in this list not only specialty names, but also values of mc_id field of Specialty model, but it is not my case to make it at the expense of something like this:

class Specialty(models.Model):
    name = CharField(max_length=255)
    mc_id = CharField(max_length=255, unique=True)

    def __str__(self):
        return self.name   '('   self.mc_id   ')'

I thought i could make it through overriding of formfield_for_manytomany() method in my admin model (associated with Doctor model) in admin.py:

@admin.register(Doctor)
class DoctorAdmin(admin.ModelAdmin):
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "specialties":
            queryset = Specialty.objects.all()
            for specialty in queryset:
                specialty.name  = '('   {specialty.mc_id}   ')'
        return super().formfield_for_manytomany(db_field, request, **kwargs)

It didn't work. I'd like to know how can i solve my problem. Thank you in advance.

UPDATE: I'd also like to make a content of specialties field in the form user-dependent:

  • if superuser tries to add new doctor he will see in the specialties field of the form values like:
    • Internal Medicine (mc1_id)
    • Neurology (mc1_id)
    • Cardiology (mc2_id)
  • if normal user which name is 'mc1_id' tries to add new doctor he will see in the form values filtered by his name and without '(mc_id)'-part. Like:
    • Internal Medicine
    • Neurology

CodePudding user response:

Just use format() in models

def __str__(self):
    return '{} {}'.format(self.name, self.mc_id)

CodePudding user response:

I think that overwrite the label_from_instance method in the form field can work for you.



class SpecialtyModelMultipleChoiceField(forms.ModelMultipleChoiceField):

    def label_from_instance(self, obj):
        obj.name   '('   obj.mc_id   ')'


class DoctorModelForm(forms.ModelForm):
    specialties = SpecialtyModelMultipleChoiceField(
        Specialty.objecs.all
        # ....
    )
    
    class Meta:
        model = Doctor
        fields = '__all__'


@admin.register(Doctor)
class DoctorAdmin(admin.ModelAdmin):
    form = DoctorModelForm
    # ....
  • Related