如何在Django中过滤模型?

时间:2019-07-16 20:56:03

标签: django

因此,我有一个称为合作伙伴的模型。企业是合作伙伴。我有一个外键字段,该字段将self作为参数来创建选择。我想要做的是遍历所有创建的合作伙伴,并筛选出属于母公司的合作伙伴。我当时在考虑说is_parent的布尔值。我该如何解决?我可以在数据库中搜索布尔值并创建选择字段或其他内容,以便获得母公司的列表吗?

我想做的是过滤父对象,或者将过滤后的对象放入choicefiled或使用它创建第二个模型,以便我可以选择父对象。

我试图过滤掉我的结果,但是没有按预期工作。

from django.db import models
from django.urls import reverse

from model_utils import Choices
from model_utils.fields import StatusField
from model_utils.models import StatusModel, TimeStampedModel
from phone_field import PhoneField
from addresses.models import Address
from 

common.utils import COUNTRIES





class Industry(models.Model):
    """ Business Industry model """
    name = models.CharField(max_length=100)

    class Meta:
        verbose_name = 'Industry'
        verbose_name_plural = 'Industries'
        ordering = ('name',)

    def __str__(self):
        return '%s' % self.name


class PartnerType(models.Model):
    name = models.CharField(blank=False,
                            help_text="Name of the role or function", max_length=64,
                            verbose_name="Partner Type", )

    class Meta:
        verbose_name = 'partner type'
        verbose_name_plural = 'partner types'

    # TO STRING METHOD
    def __str__(self):
        return '%s' % self.name


class Partner(TimeStampedModel, StatusModel):

    INVOICE_METHOD_CHOICE = (
        ("PAPER", "Paper"),
        ('EMAIL', 'Email'),
    )

    LEGAL_STRUCTURE_CHOICES = (
        ('CORPORATION', 'Corporation'),
        ('LLC', 'LLC'),
        ('SOLE PROPRIETOR', 'Sole Proprietor'),
        ('PARTNERSHIP', 'Partnership'),
    )

    PARTNER_OFFICE_CHOICES = (
        ('HEADQUARTERS', 'Headquarters'),
        ('DIVISION', 'Division Office'),
        ('SITE', 'Site'),
        ('DC', 'Distribution Center'),
    )

    ADDRESS_TYPES = (
        ('Billing', 'Billing'),
        ('Shipping', 'Shipping'),
        ('Physical', 'Physical'),
    )

    STATUS = Choices('Active', 'Inactive', 'Credit Hold',)
    name = models.CharField(blank=True, max_length=100, verbose_name='Account Name', )
    office_level = models.CharField(
        choices=PARTNER_OFFICE_CHOICES, max_length=50, blank=True,)
    trade_name = models.CharField(blank=True, max_length=100, verbose_name='Trade Name', )
    logo = models.ImageField(default='default.jpg', upload_to='partners/logos')
    industry = models.ForeignKey(
        Industry,
        blank=True,
        help_text="Industry",
        null=True,
        on_delete=models.SET_NULL,
        related_name="partners_industry", )
    csp_rank = models.IntegerField(blank=True,null=True )
    partner_types = models.ManyToManyField(PartnerType)
    account_number = models.IntegerField(blank=True, editable=True,default=0)
    vendor_number = models.CharField(blank=True, help_text="TEAZZERS account number with the partner", max_length=20,)
    phone = PhoneField(blank=True, null=True, )
    fax = PhoneField(blank=True, null=True, )
    email = models.EmailField('main email address', blank=True)
    ap_email = models.EmailField('AP email address', blank=True)
    ar_email = models.EmailField('AR email address', blank=True)
    website = models.URLField('Website', blank=True)
    description = models.TextField(blank=True)
    total_units = models.PositiveIntegerField(blank=True, null=True, verbose_name='Total units',
                                            help_text='How many locations does this organization have?')



    parent = models.ForeignKey(
        'self',
        blank=True,
        help_text="Parent Company name (if necessary)",
        null=True,
        on_delete=models.CASCADE,
        max_length=200
        )
    # if total_units > 0:
    #     status = 'Parent'
    #
    # if status == "Parent":
    #     parent = models.ForeignKey(
    #     'self',
    #     blank=True,
    #     help_text="Parent Company name (if necessary)",
    #     null=True,
    #     on_delete=models.CASCADE,
    #     related_name="partners_partner", )

    w9 = models.BooleanField(default=False, verbose_name='IRS Form W-9',
                             help_text='Have we received a completed IRS Form W-9?',)
    legal_structure = models.CharField(
        choices=LEGAL_STRUCTURE_CHOICES, max_length=50, blank=True,
        help_text='How is the business structured?',)
    ein = models.CharField(max_length=9, blank=True, default='', verbose_name='Federal Employer Identification Number')
    duns = models.CharField(max_length=13, blank=True, default='', verbose_name='Dun & Bradstreet (DUNS) Number')
    gln = models.CharField(max_length=13, blank=True, default='', verbose_name='GLN (GS1 Global Location Number)')
    insurance = models.BooleanField(default=False, verbose_name='Insurance',
                                    help_text='Have we received liabilty insurance paperwork?',)
    insurance_end_date = models.DateField(blank=True, null=True, verbose_name='Insurance End Date',
                                          help_text="When does insurance on file end? "
                                                    "Please use the following format: <em>YYYY-MM-DD</em>.")
    insurance_files = models.FileField(upload_to='partners/insurance', blank=True,
                                       verbose_name='Current Insurance Paperwork')
    sales_tax = models.BooleanField(default=False, verbose_name='Sales Tax Paperwork',
                                    help_text='Have we received Uniform Sales & Use Tax Certificate?',)
    sales_tax_files = models.FileField(upload_to='partners/sales_tax', blank=True,
                                       verbose_name='Current Insurance Paperwork')
    invoice_method = models.CharField(
        choices=INVOICE_METHOD_CHOICE, max_length=64, default='paper')
    start_date = models.DateField(blank=True, null=True, verbose_name='Active Since',
                                  help_text="When we begin doing business? Please use the"
                                            " following format: <em>YYYY- 
    MM-DD</em>.")
    address_type = models.CharField(
        max_length=20, choices=ADDRESS_TYPES,blank=True)
    street1 = models.CharField(
        'Street Line 1', max_length=100, blank=True)
    street2 = models.CharField(
        'Street Line 2', max_length=100, blank=True)
    city = models.CharField('City', max_length=100, blank=True)
    state = models.CharField('State', max_length=100, blank=True)
    postcode = models.CharField('Post/Zip-code', max_length=32, blank=True)
    country = models.CharField(
        max_length=3, choices=COUNTRIES, blank=True)

    def __str__(self):
        # return self.city if self.city else ""

        return '%s' % self.full_address

    @property
    def full_address(self):
        return ' %s %s %s %s %s' % (self.street1, self.street2, self.city, 
    self.state, self.postcode)

    def get_complete_address(self):
        address = ""
        if self.street1:
            if address:
                address += ", " + self.street1
            else:
                address += self.street1
        if self.street2:
            if address:
                address += ", " + self.street2
            else:
                address += self.street2
        if self.city:
            if address:
                address += ", " + self.city
            else:
                address += self.city
        if self.state:
            if address:
                address += ", " + self.state
            else:
                address += self.state
        if self.postcode:
            if address:
                address += ", " + self.postcode
            else:
                address += self.postcode
        if self.country:
            if address:
                address += ", " + self.get_country_display()
            else:
                address += self.get_country_display()
        return address

    primary_address = models.ForeignKey(
        Address,
        blank=True,
        help_text="Primary Address",
        null=True,
        on_delete=models.SET_NULL,
        related_name="partners_industry")
    # MANAGERS
    parent_list = list()
    # META CLASS
    class Meta:
        verbose_name = 'partner'
        verbose_name_plural = 'partners'

    # TO STRING METHOD
    def __str__(self):
        return '%s' % self.name

    @property
    def full_name(self):
        return '%s %s' % (self.name, self.site_id)

    # SAVE METHOD

    def save(self, *args, **kwargs):
        super(Partner, self).save(*args, **kwargs)
        #self.account_number = self.pk + 1000

    # ABSOLUTE URL METHOD
    def get_absolute_url(self):
        return reverse('partners:detail', kwargs={'pk': self.pk})

    def get_delete_url(self):
        return reverse('partners:delete', kwargs={'pk': self.pk})

'''

2 个答案:

答案 0 :(得分:0)

假设您还有其他一些模型(上面的models.py中未显示),您只想为其选择母公司,请首先定义一个可调用对象:

parent_companies():
    return Partner.objects.exclude(parent=None).values_list('id', 'name')

然后将可调用对象用于choices=

class SomeModel(models.Model):
    some_company = models.ForeignKeyField(Partner, choices=parent_companies())

答案 1 :(得分:0)

此查询将为您提供所有级别的所有母公司 假设我们有这样的结构

  • 1是3和4的父级
  • 2是6和5的父母
  • 3是9和10的父母
  • 4是11和12的父母
  • 6个没有儿子
  • 5是7和8的父母
  • 13没有父母#父母=无

所以(1、2、3、4、5)是父母,因为每个人都有至少一个儿子

parents = ModelName.objects.exclude(parent=None).values_list('parent', flat=True).annotate(count = Count('parent')).order_by('parent')

此为您返回所有父母的ID列表 您可以获取父母的查询集,如下所示

parents_queryset = ModelName.objects.filter(id__in=list(parents))

注意:父母表示已经有至少一个儿子

如果您需要与他们一起获得没有父节点的节点,则#parent为None 并假设它没有父项,因此它是父项

new_parents_queryset = parents_queryset | ModelName.objects.filter(parent=None)
# this queryset is all the parents that have at least one son or the parents that have no parent 

这里(1,2,3,4,5,13)是父母,因为13没有父母