Search code examples
djangomezzanine

Django Nested Form - Always Showing Object instead of model details


I'm working on a Django project generated via Mezzanine. I've been able to create my models, however I want to have a form where an admin can select from a list to assign a value in a many to many or a one to many relationship. For example, I have a model for Schemas:

class Schema(AutoCreatedUpdatedMixin, SoftDeleteMixin):
    """List of all Schemas in a given database"""

    name = models.CharField(max_length=128, null=False)
    status = models.BooleanField(max_length=128, null=False, default=True, verbose_name="Is Active")
    description = models.CharField(max_length=65535, null=True, blank=True, default=None)
    database = models.ForeignKey(Database, on_delete=models.CASCADE)
    pull_requests = models.ManyToManyField(Link)
    questions = models.ManyToManyField(Question, blank=True)
    comments = models.ManyToManyField(Comment, blank=True)
    technical_owners = models.ManyToManyField(Employee, related_name='technical_owners_schemas', blank=True)
    business_owners = models.ManyToManyField(Employee, related_name='business_owners_schemas', blank=True)
    watchers = models.ManyToManyField(Employee, related_name='watchers_schemas', blank=True)

    def __unicode__(self):
        return "{}".format(self.name)

And I have a model for Employees

class Employee(AutoCreatedUpdatedMixin, SoftDeleteMixin):
    """List of people with any involvement in tables or fields: business or technical owners, developers, etc"""

    name = models.CharField(max_length=256, blank=False, null=False, default=None, unique=True)
    email = models.EmailField(blank=True, null=True, unique=True)

    def __unicode__(self):
        return "{}".format(self.employee)

An employee can own multiple schemas and a schema can be owned by multiple employees. My database has an active employee in it, however when I try to create a Schema the employee shows up as Employee Object. Rather I would want the form to show the Employee.name. How can I do this? My admin file contains the following:

class SchemasAdmin(admin.ModelAdmin):
    list_display = ['name', 'status', 'database', 'description']
    ordering = ['status', 'database', 'name']
    actions = []
    exclude = ('created_at', 'updated_at', 'deleted_at')

enter image description here


Solution

  • First of all are you using python 2 or 3? For 3, the __str__ method should be used instead of __unicode__. I am writing this because it seems that there's a problem with the __unicode__ method of Employee, which although is defined as:

    def __unicode__(self):
        return "{}".format(self.employee)
    

    th Employee class does not have an employee attribute (unless there's such an attribute in the mixins that class inherits from (AutoCreatedUpdatedMixin, SoftDeleteMixin) but I don't think that is the case.

    In any case, the problem is that you haven't defined a propery __str__ (if using python 3) or __unicode__ (for python 2) method on the Employee class - just define it like:

    return self.name
    

    and you should see the employee's name in the django admin select fields.