In our ongoing series exploring the Department of Defense’s Continuous Authorization to Operate (cATO) model, we now turn our attention to two critical components: the Secure Software Supply Chain (SSSC) and DevSecOps practices. These elements form the backbone of a robust cATO implementation, ensuring both security and agility in software development and deployment.
Continuous Authorization to Operate (cATO) is changing the way organizations approach cybersecurity and compliance in dynamic IT environments. By embedding security directly into development and operational workflows, cATO enables real-time assessment, assurance, and authorization, promoting agility without compromising security. An environment with effective personnel and processes is critical to achieving the intended goals and objectives of a cATO.
As software systems grow increasingly complex and interdependent, static and periodic compliance assessments fall short of ensuring security. Threats evolve faster than traditional systems and accreditation processes can adapt, creating vulnerabilities or weaknesses in the software supply chain and operational lifecycle.
The cATO approach addresses these challenges by shifting from static, point-in-time approvals to a dynamic, continuous assessment and authorization model. This shift requires integrating SSSC and DevSecOps as critical enablers of security, resilience, and agility.
The software supply chain encompasses all components, dependencies, and processes involved in developing, deploying, and maintaining software applications. A compromised supply chain can lead to breaches that affect downstream systems, organizations, and even national security, as seen in incidents like the SolarWinds attack (SolarWinds, 2021) and XY/libzma.
Key principles for securing the software supply chain include:
[1] https://github.com/tukaani-project/xz/commit/e93e13c8b3bec925c56e0c0b675d8000a0f7f754
DevSecOps integrates security into every stage of the software development lifecycle (SDLC), fostering a culture of “secure by design.” By automating security practices and embedding them into CI/CD pipelines, DevSecOps enables organizations to meet cATO requirements effectively.
Key DevSecOps practices include:
The intersection of SSSC and DevSecOps represents the synergy required for achieving cATO competency. Here’s how organizations can align these practices to enable secure, compliant, and resilient IT systems:
When organizations integrate SSSC and DevSecOps into their cATO strategies, they unlock several benefits:
As organizations navigate increasingly complex cybersecurity landscapes, the adoption of cATO frameworks, supported by secure software supply chains and DevSecOps practices, is no longer optional—it’s essential. By embedding security into every layer of development and operations, organizations can achieve continuous assurance and resilience while staying compliant with evolving regulations.
With the right combination of people, processes, and technologies, cATO empowers organizations to innovate securely, keeping pace with the demands of modern IT ecosystems.
References
As the Department of Defense continues accelerating capability delivery to warfighters, agility, and modern software development are an integral part of the process. Delivering new features rapidly requires an authorization process to keep pace with continuous change for a developing capability. To tackle these challenges, the DoD introduced Continuous Authorization to Operate (cATO)—a new way to ensure security without impeding progress.
At BreakPoint Labs, we’ve been at the forefront of this paradigm shift, supporting critical DoD cyber missions and accelerating software delivery to users. We’ve had the opportunity to assist organizations in transitioning from a control assessment point-in-time approach to focusing on continuous risk determination and authorization through demonstrated continuous assessing, monitoring, and risk management. Our experience has given us unique insights into the transformational approach that is changing how the Department evaluates and authorizes highly effective development, security, and operations (DevSecOps) practices within a software development environment. As such, we’re introducing a 5-part series titled Unpacking the DoD’s cATO Evaluation Criteria.
Continuous Authority to Operate (cATO) is a framework that grants an organization’s systems or networks continuous authorization to assess whether they meet the required security standards. As opposed to traditional “ATO” processes, which require a static cycle of approval, usually every 3 years, cATO offers dynamic, ongoing authorization based on the current security state of systems in runtime.
The DoD defines cATO as: “The state achieved when an organization that develops, secures, and operates a system has demonstrated enough maturity in maintaining a resilient cybersecurity posture that traditional risk assessments and authorizations become redundant.”2
This approach aligns with the DoD’s Software Modernization Strategy, pushing for better DevSecOps practices and faster, more secure software deployment. The March 2025 State of DevSecOps report published by the DoD CIO describes DevSecOps as a critical enabler of the shift to cATO, noting that over 50 DoD software factories are now delivering code using DevSecOps practices.
The traditional ATO process was sufficient when systems were less complex and security challenges were more predictable. However, with the rise of cloud technologies, continuous deployment models, and ever-evolving cybersecurity threats, organizations found that static authorization led to blind spots in security compliance.
This is where cATO comes into play. Instead of evaluating systems at predefined intervals, cATO ensures systems remain compliant through ongoing assessments, allowing organizations to maintain security postures dynamically without significant downtime.

The DoD’s shift to cATO also incorporates Zero Trust principles. The March 2025 State of DevSecOps report explicitly frames cATO as incorporating real-time assessment, Zero Trust principles, and DevSecOps to secure the supply chain against emerging threats. Organizations building toward cATO should treat Zero Trust architecture as a foundational element, not a parallel initiative.
As organizations prepare for cATO evaluation, they should focus on:
DevSecOps Platform (DSOP): The set of tools and automation that supports software development, including secure pipelines and control gates.
Processes: Workflows and practices that ensure continuous risk management and seamless integration of security.

People: The skills, training, and collaboration between teams responsible for development, security, and operations. Building a culture of security is just as important as the technology.
For Military Services and DoD Agencies and Field Activities, cATO isn’t just a buzzword—it offers advantages in the form of:
To implement cATO, organizations need to adopt a blend of automation tools, monitoring platforms, and updated security practices.
Key steps include:
As we dive deeper into cATO Evaluation Criteria throughout this series, we’ll explore each of these pillars in detail and offer practical insights and strategies for implementation. We’ll draw on our extensive experience supporting critical DoD initiatives to provide a roadmap for organizations looking to embrace this new standard in cybersecurity and software deployment.
The path to cATO is less about process change and more about the shift in how software development and security are approached. cATO offers DoD Components a modernized authorization process for dynamic, resilient software development environments to deliver secure, scalable, and reliable software at the speed modern warfare demands.
A traditional Authorization to Operate is a point-in-time approval, typically renewed every three years, based on a compliance review conducted at a specific moment. A Continuous Authorization to Operate replaces that static cycle with ongoing authorization based on the real-time security state of the system. The DoD defines cATO as the state achieved when an organization has demonstrated enough maturity in maintaining a resilient cybersecurity posture that traditional risk assessments become redundant. Rather than proving compliance at intervals, organizations must demonstrate continuous monitoring, active cyber defense, and a secure software supply chain as ongoing capabilities.
The DoD cATO framework rests on three pillars. The first is Continuous Monitoring (ConMon), which requires near real-time visibility into Risk Management Framework controls, with aggregated security data available to authorizing officials continuously rather than at scheduled intervals. The second is Active Cyber Defense (ACD), which requires real-time threat response, integration with Cybersecurity Service Providers, and a regular cadence of penetration testing and vulnerability assessments. The third is Secure Software Supply Chain (SSSC), which requires security to be integrated throughout the software development lifecycle using approved DevSecOps platforms, automated control gates, and Infrastructure as Code. Each pillar is covered in detail in this series.
The March 2025 State of DevSecOps report published by the DoD CIO describes DevSecOps as a critical enabler of the shift from point-in-time risk assessment to continuous authorization to operate. An organization practicing DevSecOps is building the pipeline, automation, monitoring, and culture that cATO requires. The report notes that cATO incorporates real-time assessment, Zero Trust principles, and DevSecOps to secure the supply chain against emerging threats. DevSecOps is the methodology that makes continuous assessment operationally possible. cATO is the authorization outcome that recognizes that maturity.
The DoD’s March 2025 State of DevSecOps report explicitly frames cATO as incorporating Zero Trust principles alongside real-time assessment and DevSecOps. Zero Trust requires continuous verification of every user, device, and connection rather than assuming trust based on network location or prior authorization. This aligns directly with cATO’s requirement for continuous rather than periodic security assessment. Organizations building toward cATO should treat Zero Trust architecture as a foundational requirement, not a parallel initiative.
DevSecOps is the practice of integrating security into software development and operations continuously rather than treating it as a phase at the end of the development cycle. cATO is the DoD authorization framework that recognizes and rewards that maturity. An organization practicing DevSecOps is building the foundational capability that cATO requires. DevSecOps is the methodology. cATO is the formal recognition that an organization’s development, security, and operations practices are mature enough that traditional point-in-time risk assessments become redundant.
The Software Engineering for Continuous Delivery of Warfighting Capability guide is published by the Office of the Under Secretary of Defense for Research and Engineering. It provides guidance for DoD Program Management Offices, systems engineers, and acquisition officials on modern software development practices. The guide has gone through three revisions: initial release in April 2023, a December 2024 revision that clarified Agile and DevSecOps terminology and metrics, and a July 2025 revision that substantially updated guidance on AI and machine learning. For cATO programs, the guide defines the engineering and DevSecOps practices that underpin the Secure Software Supply Chain pillar of cATO evaluation.
Penetration testing is an explicit requirement under the Active Cyber Defense pillar of cATO. It’s not a one-time compliance gate but a recurring component of the continuous assessment posture. Organizations pursuing cATO need to demonstrate a regular cadence of adversarial testing as evidence that security is actively managed. The findings from penetration tests feed directly into the continuous risk determination process and give the Authorizing Official current data on exploitable risk rather than a compliance status based on a prior snapshot.
The Authorizing Official accepts risk on behalf of the organization and grants the authorization to operate. In a traditional ATO, this decision is based on a point-in-time assessment package reviewed periodically. In cATO, the Authorizing Official needs continuous, near real-time visibility into the system’s security posture so risk decisions can be made as the environment changes rather than on a fixed review schedule. This shifts the AO from periodically reviewing static documentation to maintaining ongoing awareness through a live security dashboard.
Infrastructure as Code means that system and environment configurations are defined and managed through code rather than manual processes. For cATO, IaC matters because it creates a consistent, auditable, and repeatable deployment process where security controls are enforced programmatically at every deployment. It reduces configuration drift, the gradual deviation of a live system from its authorized security baseline, which is one of the core failure modes that point-in-time authorization processes cannot detect between review cycles.
The DoD defines a software factory as a collection of people, tools, and processes that enables teams to continuously deliver value by deploying software to meet the needs of a specific community of end users. The March 2025 State of DevSecOps report notes there are over 50 DoD software factories now using DevSecOps to deliver code into production. Software factories represent the organizational implementation of the DevSecOps practices that cATO evaluation is built around. A program operating with a software factory has the foundational infrastructure that cATO requires.
cATO is not universally mandatory, but it is the preferred authorization approach for programs using continuous deployment models under the DoD Software Modernization Strategy. Programs delivering software updates frequently and operating in cloud or DevSecOps environments are the primary intended audience. Programs still operating on traditional waterfall development cycles may find that a traditional ATO remains more practical, but the direction of DoD policy is clearly toward continuous authorization for modern software development environments.
There is no fixed timeline because cATO is a state of demonstrated maturity rather than a certification with a defined endpoint. Organizations starting from a traditional ATO posture should expect the transition to take significant time, as it requires building or maturing pipelines, monitoring tooling, DevSecOps practices, and organizational culture across development, security, and operations teams. The March 2025 State of DevSecOps report identifies bureaucratic inertia aligned to traditional approaches as one of the primary barriers, noting that existing processes across cyber, test and evaluation, acquisition, and requirements all need to be realigned toward rapid incremental delivery.
The primary reference documents are the DoD CIO’s Continuous Authorization to Operate memo, the DevSecOps Continuous Authorization to Operate Evaluation Criteria, the March 2025 State of DevSecOps report published by the DoD CIO at dodcio.defense.gov, and the Software Engineering for Continuous Delivery of Warfighting Capability guide published by OUSD R&E and last updated July 2025 at cto.mil. For programs operating within a specific military service, check for service-specific implementation guidance in addition to these DoD-level documents.
1. Department of Defense Software Modernization Strategy – DoD CIO
2. Continuous Authorization To Operate (cATO) Memo – Department of Defense
3. DevSecOps Continuous Authorization to Operate Evaluation Criteria – DoD CIO
4. DevSecOps Continuous Authorization to Operate Evaluation Criteria – DoD CIO
Software testing is more than just a step in the development process; it’s a critical practice that drives the quality, security, and reliability of the software we deliver. At BreakPoint Labs, we’ve integrated rigorous testing throughout the entire development lifecycle, ensuring that every piece of software we produce meets our high standards and aligns with the needs of our clients and end users’ expectations.
Integrated Testing Throughout the Lifecycle
We believe in embedding testing into every phase of the development lifecycle, starting from the earliest stages and continuing through to post-deployment. By designing and executing tests from the beginning, issues or bugs are caught early, preventing them from escalating into larger problems. This proactive approach, combined with continuous testing as the software evolves, ensures a smoother development process and results in a more robust, reliable final product or service.
Embracing Automation
Leveraging technology to deliver effective and sustainable capabilities is a core tenant of BreakPoint Labs. Automation is a key part of our testing strategy. By automating repetitive and complex tests, we can quickly verify that our software works as intended under various conditions. This not only saves time but also improves accuracy and consistency, giving us the confidence that our software and services can handle real-world demands under realistic constraints and against sophisticated actors.
A Comprehensive Testing Strategy
Our approach to testing is comprehensive and covers every aspect of the software:
Each of these testing methods is designed to address specific aspects of the software, ensuring that the final product is well-rounded and ready for deployment.
Building Confidence and Streamlining the ATO Process
Rigorous testing isn’t just about making sure the software works—it’s about building trust. Thorough testing gives stakeholders the confidence that the software will perform reliably in the real world.
Additionally, our detailed testing process supports the Authority to Operate (ATO) process. By documenting every step of our testing, we create artifacts that are essential for gate analysis and compliance reviews. These artifacts demonstrate that the software meets all security and operational requirements, making it easier to secure the necessary approvals and get the software into the hands of users quickly and efficiently. A good example that we will dig into is “chaos testing”.
Chaos Testing
When writing chaos tests, the objective is to introduce failures and observe how the system responds to ensure resilience. Using a tool like ChaosToolkit, you can simulate various failure scenarios, such as resource constraints or random service disruptions. In one of my tests on a sample Django application, we found that it handled the load when utilizing 1-3 CPU cores but failed when pushed to 4 cores, uncovering scalability issues. In this stress test, the tool was configured to fully utilize 4 CPU cores for 10 seconds, simulating a heavy computational workload that the application could not handle under the increased pressure. Another test involved randomly restarting containers to verify they would come back up and remain accessible, which is essential for maintaining high availability. When writing chaos tests, start with a clear hypothesis, such as ensuring services remain functional under stress or after restarts. Use tools like ChaosToolkit to automate these tests in controlled environments, and always monitor logs for unexpected behaviors.
Test Scenarios utilized ChaosToolKit, Django, and Docker
Django Application successfully handling 3 CPU cores of stress:


Django Application failing to handle 4 CPU cores of stress:


In summary, our software testing approach is more than just catching bugs. It’s about ensuring quality, building trust, and supporting compliance so that every piece of software we deliver is ready to perform when it matters most.
As technology advances, so do the threats and vulnerabilities that come with it. Now more than ever, security is a huge priority in the software development lifecycle for all industries. This is why approaches such as DevSecOps are becoming more and more utilized in these processes.
Here’s a quick overview of everything you need to know about DevSecOps and how it can enhance security and code integrity in your software development pipelines.
DevSecOps, short for Development Security Operations, is an innovative approach to software development that emphasizes the integration of security practices throughout the entire software development lifecycle.
Unlike traditional development methods that treat security as an afterthought, DevSecOps advocates for including security considerations during development from beginning to end.
During this process, automation can help us accomplish security checks, maintain the integrity of the codebase, and facilitate the deployment and management of applications across, even ones that span multiple separate domains or targeted organizational areas of the software (sales, IT, finance, etc.).
DevSecOps helps developers build and maintain more secure, resilient, and efficient applications to combat today’s ever-evolving threat landscape. Therefore, thorough security checks within the DevSecOps process are crucial to the Continuous Integration and Continuous Delivery (CI/CD) pipeline.
These checks are strategically integrated into the pipeline — ensuring every commit is checked and sanitized before it hits production. The pipeline serves to identify vulnerabilities, compliance issues, and potential threats early in the development process so it doesn’t become problematic down the road.
By implementing security checks into the CI/CD pipeline, DevSecOps ensures that security is not a separate concern but an integral part of the software development and deployment process.
Ensuring the integrity of the code base is a paramount objective in the DevSecOps CI/CD pipeline so that the software works as designed without flaws or performance issues. DevSecOps safeguards the code’s integrity by integrating security checks and automated tests at various development stages.
Utilizing custom tests within your pipeline provides confidence that you won’t inadvertently disrupt existing features or introduce unforeseen bugs as you implement new changes.
Incorporating these practices ensures reliability and security throughout the development process — ultimately leading to more efficient and dependable applications.
The DevSecOps CI/CD pipeline plays a pivotal role in simplifying the deployment and management of applications across multiple domains. Incorporating development, security, and operations practices into one function (DevSecOps) ensures that the application, from development to deployment, is fast and secure.
Through automated testing, continuous integration, and continuous delivery, developers can confidently deploy code across various domains, knowing that security measures are in place to detect and mitigate potential vulnerabilities.
There’s also pipeline flexibility that allows for configurations for different domains, organizational functions, or clients, where you can implement changes based on the environments while maintaining consistency. This approach streamlines deployment and facilitates efficient management — ensuring confidence in the application in every domain.
DevSecOps represents an approach to software development that prioritizes security throughout the entire process. It fosters a proactive stance on security and ensures code reliability and safety from start to finish.
By integrating automated checks and ensuring consistency across multiple domains, DevSecOps equips developers to confidently navigate the ever-evolving digital landscape. This strategy allows teams to create software applications that meet today’s challenges while adapting to future uncertainties.
Solutions for Orchestrating Infrastructure and Services
Combining the capabilities of Ansible and GitLab gives you an excellent infrastructure automation solution for streamlining software provisioning and deployments while also boosting collaboration between your teams.
In this article, we cover how the open-source application management tool and Git repository can simultaneously meet your software performance, standardization, and security goals.
Ansible is a popular open-source tool for configuration management, application deployment, task automation, and orchestration within IT environments. It lets you simplify and streamline various IT operations to make them more efficient and less error-prone.
Ansible playbooks are excellent resources that provide consistent configurations across entire infrastructures. This automation serves two main purposes:
Ansible stands out for its simplicity and minimal dependencies. Its agentless architecture eliminates the need for the installation and maintenance of agents on managed systems — making it lightweight and efficient.
This separates Ansible from other management tools, such as Puppet or Chef, which come with the added overhead of agent management across systems. Ansible delivers organizations’ automation and orchestration without the complexity — aligning with the principles of efficiency and ease of use often sought in modern IT environments.
Ansible’s role extends beyond initial setup and configuration. It contributes to continuous monitoring and enforcement of security policies. Through its automation capabilities, Ansible can continually run network security assessments on things like user access, device integrity, and application security.
When anomalies or deviations from security policies are detected, Ansible takes immediate corrective actions, such as isolating compromised devices or revoking access credentials. The real-time response to security events aligns with high confidence in the stability of the environment. The solution provides a proactive and adaptive security orchestration approach where you can enforce policies dynamically based on advanced data analytics on contextual information and cybersecurity risk assessments.
After initial configurations are in place, Ansible becomes essential to distinguishing normal from abnormal within the environment, and further, it automates the enforcement of the network security policies.
Setting up a GitLab repository for Ansible playbooks and associated application code is fundamental in integrating automation tools. When trying to uncover who and what is on the network and find tools to leverage for Identity, Credential, and Access Management (ICAM), the GitLab + Ansible tech stack shines as a flexible and formidable solution.
Hosting GitLab behind a virtual private network (VPN) can serve as a critical tenet of a stable architecture — ensuring network access is never assumed and is subject to continuous verification. GitLab further offers a robust role-based access control (RBAC), which you can configure to align with the organization’s security policies to ensure that only authorized personnel have repository and children project access.
GitLab offers a robust Infrastructure as a Code (IaC) platform. It comes in the form of Ansible playbooks and related configurations — allowing for streamlined organization of Organizations, Groups, Projects, Repositories, and a Container Registry for customized Docker images and other tailored assets.
These capabilities let you systematically manage version control, collaboration, and documentation of infrastructure configurations.
Version-controlling infrastructure configurations with GitLab offer several advantages:
GitLab’s CI/CD features seamlessly integrate with Ansible playbooks to automate the testing and deployment. You can configure CI/CD pipelines in GitLab to automatically trigger when changes are pushed to a repository. These pipelines can be customized to run specific tasks under certain conditions based on the current branch — ensuring that updates to enterprise cybersecurity policies, configurations, and infrastructure are continuously assessed for correctness.
You can also configure GitLab’s role-based access control (RBAC) to ensure additional code reviews before deployment. This automation further enforces consistency in security orchestration for organizational policies and eliminates the risk of human error. CI/CD’s ability to automatically roll back changes in case of failures ensures the network maintains non-stop stability and security.
Finally, CI/CD enhances traceability and transparency — letting you leave audit trails and reports on every change made to the network infrastructure. This level of control is essential in maintaining a robust Zero Trust Architecture where trust is never assumed and verification is continuous.
Agility is paramount in modern IT operations for organizations to adapt to evolving challenges and seamlessly transition across various environments and domains. GitLab and Ansible working together in the technology stack empower organizations to achieve such agility.
An example of this capability in action is when you need to deliver rapid infrastructure scaling to support a sudden surge in user demand. The GitLab-Ansible stack allows for the swift updating of infrastructure code in the GitLab repository.
Plus, with Ansible playbooks configured within GitLab’s CI/CD pipelines, you can automate the provisioning of additional servers and application deployments — ensuring the infrastructure can handle the increased load. With the version control capabilities, you can quickly reverse these changes if and when necessary.
As your organization’s needs evolve, it can use the Ansible and GitLab stack to seamlessly transition to different environments, whether expanding to new geographic regions, moving from on-premise to the cloud, switching cloud providers, or some combination of the above.
The GitLab and Ansible stack enables organizations to respond quickly to changing market demands, scale infrastructure as required, and navigate diverse IT environments with ease. This agility is a tangible advantage in an ever-evolving IT landscape.
The Django 2.1 ORM is quite capable. Though it does not cover every conceivable use case, it handles nearly all simple queries and many more complex queries as well. Still, there are times when I wish the ORM had some capability that it doesn’t. That’s happened a couple times this year as I’ve been learning Django. This post tells about a new QuerySet method we developed that’s been useful to us.
The Django ORM allows you to attach data to objects returned from a QuerySet using annotate() and aggregate(). These methods often do exactly what you need. However, there are cases that the Django ORM doesn’t handle. For example, what if I want to attach data that isn’t part of the model or a related model to an object? Perhaps the data is queried from another database or a web API. Maybe the data I need is in an unrelated model and for whatever reason I’m not at liberty to add a relationship. Or perhaps attaching the data via annotate() is theoretically possible but is cumbersome and would be much easier to do in Python code. Another case is attaching data obtained from a raw SQL query: Django has no way to join the result of a raw SQL query to a QuerySet.
From what I can tell, the standard technique in these cases is to use values() to make the QuerySet return a dictionary and then use Python code to add to that dictionary. This can work fine, but I may not want to convert the returned model instances into a dictionary. One example of this is when working with the Django REST Framework, where my serializer expects object instances. Another case is when I want to later call methods on the returned objects, which won’t work once they’ve been converted to dictionaries.
We kept running into situations like this, so I decided to look for a clear and easy to use solution. The result of my search was AugmentableQuerySet. This subclass of QuerySet has a single new public method augment() available. Let me give a trivial example of how to use it.
[code language="py"]
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
model_number = IntegerField()
base_price = models.DecimalField(max_digits=8, decimal_places=2)
tax_class = CharField(max_length=1)
objects = AugmentableQuerySet().as_manager()
def format_name_and_model(product):
return f'{product.name} model {product.model_number}'
products = Product.objects.augment(name_and_model=format_name_and_model)
for prod in products:
print(prod.name_and_model)
[/code]
This silly task could be accomplished with annotate(), but it gives an idea of how augment() works: it takes one or more keyword arguments, where the argument name is the field name to be added to the object and the argument value is a function that is called on the object to calculate the value for the new field. It can be anything that is callable: a function, a lambda or a class with a __call__ method. The callable must take a single argument, which is the object (or dictionary) returned by the QuerySet.
Here is a more realistic example that shows you can attach multiple fields to the object.
[code language="py"]
def WarrantyLookup(user):
def lookup(obj):
params = {'country': user.address.country,
'model_number': getattr(obj, 'model_number')}
r = requests.get(WARRANTY_URL, param=params)
return r.json()['period']
return lookup
def product_price(product, user, tax_table):
return complex_calculation_of_tax(product.base_price,
product.tax_class,
user.address.zip_code,
tax_table)
products = Product.objects
.augment(warranty_period=WarrantyLookup(request.user),
price=lambda p: product_price(p, request.user, tax_table))
for prod in products:
print(prod.name, prod.warranty_period, prod.price)
[/code]
The WarrantyLookup is in upper camel case to fit the Django convention for query expressions. (For example, Sum or ExpressionWrapper.) Neither warrant_period nor price are part of the model, but the Product instances returned by the augmented QuerySet have both of those fields.
Below is the implementation of AugmentableQuerySet. It works with QuerySets that return model object instances or dictionaries. It could be modified to handle tuples returned by values_list(). Note that if you call the values() method on the QuerySet to generate dictionaries, the call to augment() must come after it. This is because values() replaces the QuerySet iterator that augment() has wrapped, so the call to augment() will have no effect.
[code language="py"]
class AugmentableQuerySet(models.QuerySet):
@staticmethod
def _make_iterable(iterable, expressions):
class AugmentIterable(iterable):
def __iter__(self):
for row in super().__iter__():
for field, func in expressions.items():
if isinstance(row, dict):
row[field] = func(row)
else:
setattr(row, field, func(row))
yield row
return AugmentIterable
def augment(self, **expressions):
clone = self._chain()
clone._fields = tuple(expressions)
clone._iterable_class = self._make_iterable(self._iterable_class, expressions)
return clone
objects = AugmentableQuerySet().as_manager()[/code]
augment() adds a new field to all objects returned by a queryset, the value of which is the result of applying a function to the object. The implementation is fairly simple, though you don’t need to understand the code above to use augment(). One potential issue is that _iterable_class is not a documented part of Django 2.1, so a new version of Django might break our code. We have some simple tests around the AugmentableQuerySet class that should catch any problems.
We created AugmentableQuerySet to make our Django code shorter and easier to understand. It has been working well for us so far. We may improve the implementation as we gain more experience with it, or perhaps we’ll find a better way to accomplish what we want. For now, though, this has been a successful addition to our Django toolbox.