Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
103 views
in Technique[技术] by (71.8m points)

python - How to structure models in Django?

I'm working on a project using Python(3.7) and Django(3) in which I have to create some models to store reports. There are 4 different models to represents each type of report with only 2 common fields(RequestId, InstCode) but the rest of the fields are different. In the end, I have to display the 10 recent reports (mixed from all models) on the home page.

Here's how I have implemented my models at the moment:

From models.py:

class DistributionReport(models.Model):
    RequestId = models.CharField(max_length=256, blank=False, default=0)
    InstCode = models.CharField(max_length=3, blank=False)
    Currency = models.CharField(max_length=3, blank=False)
    Denomination = models.IntegerField(blank=False, default=0)decimal_places=2)
    date = models.DateField(default=datetime.date.today)

    class Meta:
        verbose_name = 'Distribution Report'

    def __str__(self):
        return self.RequestId


class ExpenditureReport(models.Model):
    RequestId = models.CharField(max_length=256, blank=False, default=0)
    InstCode = models.CharField(max_length=3, blank=False)
    StaffExpenditure = models.DecimalField(max_digits=12, decimal_places=2)
    Month = models.IntegerField(blank=False, default=0)
    Quarter = models.IntegerField(blank=False, default=0)
    Year = models.IntegerField(blank=False, default=0)

    class Meta:
        verbose_name = 'Expenditure Report'

    def __str__(self):
        return self.RequestId


class StorageReport(models.Model):
    RequestId = models.CharField(max_length=256, blank=False, default=0)
    InstCode = models.CharField(max_length=3, blank=False)
    Currency = models.CharField(max_length=5, blank=False)
    Denomination = models.IntegerField(blank=False, default=0)
    date = models.DateField(default=datetime.date.today)

    class Meta:
        verbose_name = 'Processing Report'

    def __str__(self):
        return self.RequestId


class AssetsReport(models.Model):
    RequestId = models.CharField(max_length=256, blank=False, default=0)
    InstCode = models.CharField(max_length=3, blank=False)
    AssetClassificationId = models.IntegerField(blank=False, default=0)
    VaultCapacity = models.DecimalField(max_digits=10, decimal_places=2)
    Year = models.IntegerField(blank=False, default=0)
    HalfOftheYear = models.IntegerField(blank=False, default=0)

    class Meta:
        verbose_name = 'Assets Report'

    def __str__(self):
        return self.RequestId

What is the best way to structure these models, so I can query the recent reports ( It can be of any type)?

question from:https://stackoverflow.com/questions/65839837/how-to-structure-models-in-django

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Look into how normalization works, since all models have 2 common fields lets say you have a table called Report and it has the fields RequestId and InstCode. Now all your other models can be said to be in a XYZReport is a Report kind of relationship.
You can achieve this using a OneToOne Field like so:

class Report(models.Model):
    RequestId = models.CharField(max_length=256, blank=False, default=0)
    InstCode = models.CharField(max_length=3, blank=False)
    DISTRIBUTION = 'DI'
    EXPENDITURE = 'EX'
    STORAGE = 'ST'
    ASSETS = 'AS'
    REPORT_TYPE_CHOICES = [
        (DISTRIBUTION, 'Distribution Report'),
        (EXPENDITURE, 'Expenditure Report'),
        (STORAGE, 'Storage Report'),
        (ASSETS, 'Assets Report'),
    ]
    report_type = models.CharField(
        max_length=2,
        choices=REPORT_TYPE_CHOICES,
        default=DISTRIBUTION,
    )
    # Any more common fields

class DistributionReport(models.Model):
    report = models.OneToOneField(
        Report,
        on_delete=models.CASCADE,
        related_name = 'distribution_report'
    )
    # Other fields

# Other Report models in similar fashion

Now whenever making an object of any kind of report also make an object of Report and assign it to report attribute of the models. Save both the models, also to figure out what kind of report an instance of Report is add the relevant report_type to the report instance like so:

report.report_type = Report.DISTRIBUTION # In case of Distribution Report

To figure out whether an instance of Report is of a particular type:

report.report_type == report.DISTRIBUTION # will get whether Report is a DistributionReport

To get the specific types object use the related_name set in the OneToOne Field:

distribution_report = report.distribution_report

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...