DickyS
DickyS

Reputation: 115

Count the number of objects in another model

I have two models in different apps: Program in programs and Contact in contacts. Each program can have many contacts. I want to have a field in Program called database_quantity that shows how many contacts are associated with that program. Here is what I have tried so far which is giving me this error: ImportError: cannot import name 'Contact'. I think this has to do with circular referencing but I am lost with how to proceed.

programs models.py

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from contacts.models import Contact

class Program(models.Model):
    program_code = models.CharField(max_length=6)
    program_format = models.ForeignKey(ProgramFormat, models.SET_NULL, blank=True, null=True)
    program_type = models.ForeignKey(ProgramType, models.SET_NULL, blank=True, null=True)
    program_board = models.ForeignKey(RealEstateBoard, models.SET_NULL, blank=True, null=True)
    article_content_type = models.ForeignKey(ArticleContentType, models.SET_NULL, blank=True, null=True)
    program_name = models.CharField(max_length=60)
    date_created = models.DateTimeField(default=timezone.now)
    client = models.ForeignKey(User, on_delete=models.CASCADE)

    def get_database_quantity(self):
        database_quantity = Contact.objects.all().filter(Contact.author=Program.client)

        return database_quantity

    database_quantity = property(get_database_quantity)

contacts models.py

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
from programs.models import Program

class Contact(models.Model):
    first_name1 = models.CharField(max_length=100, verbose_name='First Name')
    last_name1 = models.CharField(max_length=100, verbose_name='Last Name', blank=True)
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    active_status = models.BooleanField(default=True)
    program_code = models.ForeignKey(Program, on_delete=models.DO_NOTHING, null=True, blank=True)

Settings Installed Apps

INSTALLED_APPS = [
    'blog.apps.BlogConfig',
    'users.apps.UsersConfig',
    'contacts.apps.ContactsConfig',
    'programs.apps.ProgramsConfig',
    'crispy_forms',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'import_export',
]

contacts apps.py

from django.apps import AppConfig


class ContactsConfig(AppConfig):
    name = 'contacts'

Upvotes: 0

Views: 206

Answers (1)

Ozgur Akcali
Ozgur Akcali

Reputation: 5482

1- You can define your ForeignKey mappings with strings instead of Model references, like this:

program_code = models.ForeignKey('programs.Program', on_delete=models.DO_NOTHING, null=True, blank=True)

So that you won't need to import a model from another app into models.py

2 - You have several problems in your get_database_quantity method, you need to filter with model instance, not model Class, i.e self.client instead of Program.client. Also you shouldn't filter like Contact.author=..., it should be like author=.... And, to get quantity, you need .count() method of querysets. Finally, you can import other model locally to avoid circular import issues.

def get_database_quantity(self):
    from contacts.models import Contact
    database_quantity = Contact.objects.filter(author=self.client).count()

    return database_quantity

3 - You can also write get_database_quantity like this:

 def get_database_quantity(self):
    return self.client.contacts.count()

If you define your related ForeignKey field like this:

author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='contacts')

Upvotes: 1

Related Questions