Where to put object creation logic? - python

Events (and their business logic) are responsible for creating valid transactions. An Item's aggregate of Transactions determines how many of that item is currently on hand, etc.
In the world of Django (1.7), I have my row level access as model instance methods. Table level access as model Manager methods. Where shall I store my object creation logic, without leaking the domain into the view?
It feels weird creating transaction objects from the Event Manager, but appears to be the preferred way? Essentially, creating a method for each type of event?

You don't need to restrict yourself to models, managers, views or other tools framework provides. Sometimes plain function is what you are looking for.
I don't know anything about your event logic, but it seems something like this could do the trick:
def possibly_create_transaction(event):
if event.is_ok():
return Transaction()

Related

Django pure controller functions

I am wondering on how to implement pure controller functions in a Django's' "biased" MVC scheme. Let me explain it on an example.
Let's say I have a model of an Invoice, which has some attributes (say net, gross etc.). I can present it to the user using a view + template. And that's fine and easy.
But now, I want to send this invoice to a client. This is a more complicated thing, inluding more models (i.e. create an addressed Package model, get a number and let's say few other thing including creating and modifying not only Invoice model itself, but also creating and updating few other model types and instances.
I want this "action" to be available in multiple places of my web application, so going by the book I need to create a view with those actions implemented and bind it to some URL. Probably it should be implemented in POST action.
My questions are:
What kind of generic view should it be (just View? DetailView? other?).
Where should this View redirect after succesfull "send"? The simplest answer would be to redirect to the same referring page, but is this a correct way?
What if I want this "action" to be ran in background (say, send all unsend invoices at midnight) using celery or such? Of course I can make this a celery task and call it in a view. But is this clean django'ish solution? Where do you store such pure business methods in an app/project?

Django model design - How to handle multiple optional attributes?

I'm a novice in Django (but an experienced developer), and I'm starting to build my first Django project.
The project is really simple: a website where people can join events. An administrator sets an sports event, chooses the date, the kind of event (running, tennis match, bycicle ride), etc, and users can join it.
My problem is that the events can have very different data inside, depending on his category. For example, if it's a two-people team tennis match, an users should enter his name and his teammate name, their team name, etc. If the event is a bycicle ride, he can choose if he wants the difficult or the easy route, etc.
I know I can create a big model with all the attributes for every kind of event, but this is a really ugly design... There should be a common table for all registrations, with a link to the event and the basic and common data (name, address, phone, email, etc), but I don't know how to handle the specific data for each sport/event category... Any idea about how to organize this in Django models? Maybe adding a simple (key, inscription_id, type, value) table? And then, how can I render the form?
I believe what you suggested is called Entity-attribute-value model
http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model
I think there could be a good argument for keeping all data belonging to your events defined inside of a model instead of through a related generic EAV table.
To do this you could use one of django's polymorphic libraries. I have used django-model-utils' InheritanceManager in production. There are quite a few libraries including django-polymorphic.
Taking an inhertance based approach you might define a single Event model or Sport model. A sport might have a name, league, etc. All Events might have a start date and end date and sport.
Using this approach you can defined foriegn keys from your registrations to the base Event class and use djangos built in ORM to select all events or registrations of certain types, without having the additional application logic/object inspection/ property inspection of taking an EAV approach!
You can store all additional data in Text field using JSON object or other serializer.
Take look at django-jsonfield

Django: Chicken or Egg question

I am building an application that will send an API call and save the resulting information after processing the information in a APIRecord(models.Model) class.
1) Should I build a separate class in such a way that the class does the API call, processes the information (including checking against business rules) and then creates an instance of my APIRecord() class?
Or
2) Should I build a separate class with the appropriate methods for processing, and calling the API, and then in my model, override the APIRecord.save() method to call the separate class's API methods and then save the results?
Or
3) Should I build my model class with the appropriate methods for calling the API and processing the response (including checking for certain values and other business rules)?
I tried # 2 and ran into problems with flexibility (but am still open to suggestion). I'm leaning towards # 1, but I'm not sure of all the negatives yet?
it is design decision.
it depends to your design and programming interests.
i used the combination of three methods you said. if i need to some informations that can be build from other fields then i will create an internal function in model class. if i need other records of database to do something i will create an function outside of model class. and other unusual needs will be computed everywhere i need them.

Where/How should I do validation and transformations on entities in Google App Engine?

In Ruby on Rails, each model entity has a "validate_on_something" hook method, that will be called before the entity is actually persisted to the database. I would like similar functionality in Google App Engine. I am aware that you can do validation on individual Properties by passing arguments to them in their declarations. However, if I wish to do more validation than that, is there some place within the model class declaration within which I can do that?
Also, along the same lines, sometimes a entity needs modification before it is actually persisted to the database. I might need to modify (transform) the entity right before it is actually written to the database. Is there some place in the entity class declaration that would allow me to do so?
I am aware that I can put these transformations/validations outside of the class. Bu this hardly seems like good OO design. It really seems like there should be hook methods that would automatically be called in a model for these sort of needs.
So my question is, what is the most appropriate way to handle the validation and transformation of entities before they are persisted?
The best answer depends on what sort of transformations you need to do. There's no generalized pre-/post- put methods for models, but there are several other options:
As you mentioned, you can pass validation functions to Property class constructors
You can use a custom property class that generates values programmatically, such as this one.
You can modify entities as they are stored at the lowest level using api call hooks.
Are you using any kind of web framework on top of the raw app engine api's? Rails is a very high level framework. Have you looked into Django or any of the other web frameworks? You may find those are closer to rails than raw appengine entities.
Alternatively, if you want something lower level, have a look at this article on
hooks

Django signals vs. overriding save method

I'm having trouble wrapping my head around this. Right now I have some models that looks kind of like this:
def Review(models.Model)
...fields...
overall_score = models.FloatField(blank=True)
def Score(models.Model)
review = models.ForeignKey(Review)
question = models.TextField()
grade = models.IntegerField()
A Review is has several "scores", the overall_score is the average of the scores. When a review or a score is saved, I need to recalculate the overall_score average. Right now I'm using a overridden save method. Would there be any benefits to using Django's signal dispatcher?
Save/delete signals are generally favourable in situations where you need to make changes which aren't completely specific to the model in question, or could be applied to models which have something in common, or could be configured for use across models.
One common task in overridden save methods is automated generation of slugs from some text field in a model. That's an example of something which, if you needed to implement it for a number of models, would benefit from using a pre_save signal, where the signal handler could take the name of the slug field and the name of the field to generate the slug from. Once you have something like that in place, any enhanced functionality you put in place will also apply to all models - e.g. looking up the slug you're about to add for the type of model in question, to ensure uniqueness.
Reusable applications often benefit from the use of signals - if the functionality they provide can be applied to any model, they generally (unless it's unavoidable) won't want users to have to directly modify their models in order to benefit from it.
With django-mptt, for example, I used the pre_save signal to manage a set of fields which describe a tree structure for the model which is about to be created or updated and the pre_delete signal to remove tree structure details for the object being deleted and its entire sub-tree of objects before it and they are deleted. Due to the use of signals, users don't have to add or modify save or delete methods on their models to have this management done for them, they just have to let django-mptt know which models they want it to manage.
You asked:
Would there be any benefits to using Django's signal dispatcher?
I found this in the django docs:
Overridden model methods are not called on bulk operations
Note that the delete() method for an object is not necessarily called
when deleting objects in bulk using a QuerySet or as a result of a
cascading delete. To ensure customized delete logic gets executed, you
can use pre_delete and/or post_delete signals.
Unfortunately, there isn’t a workaround when creating or updating
objects in bulk, since none of save(), pre_save, and post_save are
called.
From: Overriding predefined model methods
Small addition from Django docs about bulk delete (.delete() method on QuerySet objects):
Keep in mind that this will, whenever possible, be executed purely in
SQL, and so the delete() methods of individual object instances will
not necessarily be called during the process. If you’ve provided a
custom delete() method on a model class and want to ensure that it is
called, you will need to “manually” delete instances of that model
(e.g., by iterating over a QuerySet and calling delete() on each
object individually) rather than using the bulk delete() method of a
QuerySet.
https://docs.djangoproject.com/en/1.11/topics/db/queries/#deleting-objects
And bulk update (.update() method on QuerySet objects):
Finally, realize that update() does an update at the SQL level and,
thus, does not call any save() methods on your models, nor does it
emit the pre_save or post_save signals (which are a consequence of
calling Model.save()). If you want to update a bunch of records for a
model that has a custom save() method, loop over them and call save()
https://docs.djangoproject.com/en/2.1/ref/models/querysets/#update
If you'll use signals you'd be able to update Review score each time related score model gets saved. But if don't need such functionality i don't see any reason to put this into signal, that's pretty model-related stuff.
It is a kind sort of denormalisation. Look at this pretty solution. In-place composition field definition.

Categories

Resources