I'm still new to Django and am trying to understand and implement the "fat model, skinny view" pattern. It makes sense to me that a model should be self contained for re-usability though I don't currently see the use case for this particular model.
The model is a virtual machine for one of many cloud vendors. I have a polymorphic base model, VirtualMachine which defines all the fields. I also have a specific model, VirtualMachineVendor which implements the vendor specific control function for VirtualMachine. Examples would be vm_create() or vm_delete that handle the model creation or deletion as well as the management of the cloud resource.
The view mainly processes the request and sends that to the correct model method and preparing data for the template. I want to add functionality for creating a domain record using some independent python code which communicates with the cloud provider.
Question: Should the VirtualMachine model call this domain creation method or should this be something the View calls? In general, should a model be calling other model methods within the same or different app, or should the model return control back to the view after a call?
I've also been trying to make sense of these SO Q&A making mention of a service layer for these types of methods:
Proper way to consume data from RESTFUL API in django
Separation of business logic and data access in django
Related question: is it fair then to say that fat models refer to the methods associated directly with manipulation of the model data?
This is really pretty arbitrary. I personally wouldn't put any code that calls an external API into the model itself; apart from anything else, that would complicate testing, but more generally I would treat model methods as having the database as their only dependency.
If you like, this could go in a utils module.
Related
I'm working on a client/server product. Basically, server will transfer a document to client side to do editing. The client side has full MVC architecture. The document is the model.
Now the problem are:
There are some calculation in the model that need some resources in server.
For performance reason, some part of the model should be lazy loaded.
One example is the image in a document. It didn't load when opening the document, but there is something that load the image, once it loaded it will let the document know and document will recalculate the layout.
My question is if the communication code is part of Model or Controller? Or it belongs to some Context that is neither Model nor Controller? Or the Context belongs to Model?
The model layer should be interacting with data source. In case of client-server setup where you have two separate and independent triads, the data source for client's model layer would be server's presentation layer.
Basically, your client-side's model layer becomes the user of server-side.
It will be better if you can provide some calculation example or document object model.
Let's break through the requirement:
There are some calculation in the model that need some resources in server.
This kind of calculation is better to be put at Model, because it needs resources from server. If you are put the logic at Controller, then:
The Controller need access to server (database), in which break the MVC rule. Another thing is, the Controller now know the connection (either string or physical file storage). If you add another adapter / bridge, then it is additional effort
The calculation cannot be applied to other UI-implementation. Say in .Net, you put it in Asp.Net MVC and add the calculation at Controller. If sometimes you need to support desktop UI, then the calculation cannot be used as is (because already being tainted with controller actions, added useless web dependency, etc)
For performance reason, some part of the model should be lazy loaded.
I'm not sure about your objective with this. But let we go through this. I'm assuming that you has Header model which has List of Details that need to be lazy loaded. This can be achieved with 2 approach.
First approach is to implement lazy load at the Details property, and second approach is to retrieve a list of Details given by specific Header or id, retrieved from the repository. Both of them are resulting the same. IMHO I like the second better, because with later solution, you can reuse the repository in other module, and enable you to select Details without specific Header. The placement, I believe it should be on Model.
I may misunderstand the requirement though.
What is the best practice approach to handling non-deleting entities in an N-Tier Architecture. The architecture in question has a service layer and a repository layer. The repository is the only layer that has direct access to the database (well, through an ORM). Currently, the repository layer deals mostly with CRUD operations. Should this layer handle the retrieval of entities based on a given status?
Let me explain the use of status in our system. We want to use status to delete entities. So instead of deleting a User entity, we would set its status do Deleted. Now, the User Repository exposes a Get method. Calling Get without any parameters should return all Users in the system, regardless of its Status, but if we wanted to only get Active Users, would it be best to deal with that in the Service layer, or the Repository layer. If we were to do it in the Service layer, we would need to come up with a filter on the Repository Get methods response. If we did it in the Repository layer, we would have Get take a Status enum, so you could call Get(Status.Active). What would be the best way to handle something like this?
I would suggest limiting Get(id) to retrieving the details for a specific entity and then implement some type of Find/Search functionality that accepted a SearchCriteria object to define your search parameters (such as Status). To answer your question about where to do the filter, I would suggest the database since it is optimized for query execution.
I've prototyped a web application with Django. Some parts of the model structure are currently simple Django models which currently simulate the data structure of an legacy data store that I need to integrate. These so called master data will be read only for the app. The master data is (I think) exposed via a webservice to me, but I guess this is somewhat irrelevant.
Essentially I need to create some kind of proxy object, that I swap in for the current model. I would like to leave as much as possible of the remaining application code untouched. I'm aware that this will probably limit the amount of Django magic I can use for these "faked" models (no auto generated forms, no admin interface) but I'm okay with that.
Is there anything that I could use?
In Django, the suggested software architecture is to put all business logic and data access in models.
But, some colleagues have suggested that the data access layer should be separate from the business logic (business service layer). Their justification is that the data access layer can isolate changes if a different data source is used. They also say that there is business logic that can be in more than one model.
But, when I start coding using the separate data access and business logic layers, the data access layer is simple (basically the model code that defines the db schema) and it does not seem to add much value.
Is there really value in separating out the data access from django models or does django already provide a sufficient data access layer with its ORM?
I'm looking for developers that have implemented a fair number of django apps and find out what their opinion is. This is for a small to medium sized web app.
After three years of Django development, I've learned the following.
The ORM is the access layer. Nothing more is needed.
50% of the business logic goes in the model. Some of this is repeated or amplified in the Forms.
20% of the business logic goes in Forms. All data validation, for example, is in the forms. In some cases, the forms will narrow a general domain (allowed in the model) to some subset that's specific to the problem, the business or the industry.
20% of the business logic winds up in other modules in the application. These modules are above the models and forms, but below the view functions, RESTful web services and command-line apps.
10% of the business logic winds up in command-line apps using the management command interface. This is file loads, extracts, and random bulk changes.
It's very important that view functions and RESTful web services do approximately nothing. They use models, forms, and other modules as much as possible. The view functions and RESTful web services are limited to dealing with the vagaries of HTTP and the various data formats (JSON, HTML, XML, YAML, whatever.)
Trying to invent Yet Another Access Layer is a zero-value exercise.
The answer depends on the requirements of your application.
For applications which will always use relational databases and can be coupled with a specific ORM, you do not need to separate data access and models. Django ORM is based on the active record design pattern, which supposes data access and model are together. Pro is simplicity, con is less flexibility.
Separating data access and model is only necessary when developer wants to uncouple completely data access layer and business logic. You can do it with the data mapper design pattern. Some ORMs support this design pattern, such as SQLAlchemy. Pro is more flexibility, con is more complexity.
I recommend the book "Patterns of Enterprise Application Architecture" written by Martin Fowler for more details.
I’ve been trying to wrap my head around how to expose my domain objects to the client. Whether I’m using a rich client or I’m using the web, I want to use the MVP and repository patterns.
What I’m trying to wrap my head around is how I expose my repository and model, which will be on the server. Is it even possible to expose complex business objects that have state via a web service, or will I have to use a proprietary technology that is not language/platform agnostic, like .Net remoting, EJB, COM+, DCOM, etc?
Some other constraints are that I don’t want to have to keep loading the complex domain object from the database or passing it all over the wire every time I want to do an operation. Some complex logic might be that certain areas of the screen might be disabled or invisible based on the users permissions in combination with the state of the object. Validation and error message information will also need to be displayed to the user. I want to be able to logically call a lot of my domain object operations as if it were running on the same machine.
With the web, you have free rein. You don’t have to expose your objects across service boundaries, so you can make them a rich as you would like. I’m trying to create an N-teir architecture that is rich and works when the client calling the model is on a different machine.
You can expose your domain objects like any other object through REST or web services. I think key is to understand that you will have to expose services that provide business value in a single call, and these do not necessarily map 1:1 to your repositories. So while you on the server may expect a single service call to use multiple repositories and perform various aggregations, the things you expose over any kind of web-service should be more or less complete results. The operations you expose on the service should not expose individual repositories but rather focus on meaningful operations that provide a given business value.
I hope this helps somewhat.
You can use a SOAP formater for .Net remoting,
but the resulting service will probably be hard
to consume as a service, and it will surly be very chatty.
If you want your domain model to be consumed as a service,it should be designed as a service.
As stated in domain driven design, a service is stateless, so it won't expose your objects directly. Your service should expose methods that provides meaningful business operations that will be executed as a single unit.
Usually consider that the model in your client is in a different bounded context because its concerns will be a bit different from the one on the server.
What I’m trying to wrap my head around
is how I expose my repository and
model, which will be on the server. Is
it even possible to expose complex
business objects that have state via a
web service, or will I have to use a
proprietary technology that is not
language/platform agnostic, like .Net
remoting, EJB, COM+, DCOM, etc?
A good domain model is going to be highly behavioral and designed around the problem domain (and your discussions with domain experts), I'd thus argue against designing it to be exposed to remote consumers (in the same way that designing it from the database or GUI first is a bad idea).
Instead I'd look at using a style like REST or messaging and decide on the interface you want to expose and then map to/from the domain. So if you went with REST you'd design your resources and API (URL's, representations, etc.) and then you'd need to fulfill it from the domain model.
If this becomes un-natural then you can always have multiple models, for example mapping a seperate read-only presentation specific model to the same data-source (or which wraps the complex behavioral domain model) is an approach I've used several times.
Some other constraints are that I
don’t want to have to keep loading the
complex domain object from the
database or passing it all over the
wire every time I want to do an
operation
Look at caching in HTTP and supporting multiple representations for a resource, also look at caching within your data-access solution.
Validation and error message
information will also need to be
displayed to the user. I want to be
able to logically call a lot of my
domain object operations as if it were
running on the same machine.
You can either represent this as a resource or more likely look at HTTP status codes and the response bodies you'd want to use in those situations.