What methods should a model contain - python

When I have a model Car where users can upload a single picture to, I can create a property ImageFile in Django to achieve that. Now I would also like to get the metadata from this file and save them to the database.
Now I'm very unsure where I should place this method a how I should design it. It would be obvious, to have a method like _set_exifdata() or _update_exifdata() that is called every time I set an Image to the model.
Or a method get_exifdata(imagefile) that returns a dict of exifdatas. But should this method be part of the Car model? Actually, I won't need it anywhere else, so it does not make sense to put it in a general helper class. But on the other hand, I would prefer to split methods in "retrieving data" and "setting data", so _update_exif() for example would do both of it in once, and maybe that's OK in design ways, but maybe its not and there is some rules of model design I should know and respect here.
I hope someone can help me with some guidelines for model design (especially for django) and what methods should be part of methods and which should not.

if you using only for the car then you can put that value in the model save method,
which will get call every time whenever you will update the data.

Related

Show change log history for model instance using django-reversion

Using:
django 1.10 reversion 2.0.8.
My question is how to show a nice list of changes done to a given model instance. By that I mean that the user can quickly see a list of all the changes (new values for fields) in all revisions. He doesn't need o see all the fields only the new values of the changed ones.
So I found that a good tool for storing changes is django-reversion. However, I cannot find a solution for my problem which as I mentioned is to show a nice change-log history for a given model instance.
I found solution that can compare two revisions django-reversion-compare, but that is not what I am looking for. Maybe there is a better tool for that ?
The task is too quickly show to user what was changed by who and when. The model is simple and doesn't store a lot of data. It does store however foreign keys.
I was also looking to do the same, and after reading up a few SO posts, docs etc., it seems I had to roughly choose the solution from one of the following 3 approaches:
1) Fetch the existing model instance before saving the new model instance. Compare each field. Put the changed field in reversion.set_comment('(all changes here)'). Continue with saving the model instance.
2) Save a copy of the old fields separately in model's __init__() and later compare the new fields with them (in model's save()) to track what changed. Put the changed fields in reversion.set_comment('(all changes here)'). Continue with saving the model instance. (This approach will save a DB lookup)
3) Generate a diff using django-reversion's low-level API and integrate with the Admin somehow
I ended up using django-reversion-compare which worked great for me showing the edits wiki-style (which may be using (3) above anyways)
django-reversion's developer also confirmed (3) as a better option which also avoids race condition.
If you would like to explore different options, this is a great SO post with lots of good ideas with their pros/cons.
(I am also on Django 1.10)

Where to Start with Custom Reporting Python/Django

I'm trying to find a way to build a robust report library that I can use with a Django project.
Essentially, what I'm looking for is a way to access a list of functions(reports) that I can allow an end-user to attach to a Django model.
For example, let's say I have an Employee object. Well, I have a module called reports.py that has a growing list of possible reports that take an employee object and output a report, usually in JSON form. There might be number of timecards submitted, number of supervisions created, etc.
I want to be able to link those changing report lists to the Employee object via a FK called (job description), so admins can create custom reports per job description.
What I've tried:
Direct model methods: good for some things, but it requires a programmer to call them in a template or via API to generate some output. Since the available reports are changing, I don't want to hard-code anything and would rather allow the end-user to choose from a list of available reports and attach them to a related model (say a JobDescription).
dir(reports): I could offer up a form where the select values are the results from dir(reports), but then I'd get the names of variables/libraries called in the file, not just a list of available reports
Am I missing something? Is there a way to create a custom class from which I can call all methods available? Where would I even start with that type of architecture?
I really appreciate any sort of input re: the path to take. Really just a 'look in this direction' response would be really appreciated.
What I would do is expand on your dir(reports) idea and create a dynamically loaded module system. Have a folder with .py files containing module classes. Here's an example of how you can dynamically load classes in Python.
Each class would have a static function called getReportName() so you could show something readable to the user, and a member function createReport(self, myModel) which gets the model and does it's magic on it.
And then just show all the possible reports to the user, user selects one and you run the createReport on the selected class.
In the future you might think about having different report folders for different models, and this too should be possible by reflection using model's __name__ attribute.

Django MVT design: Should I have all the code in models or views?

I'm pretty novice so I'll try to explain in a way that you can understand what I mean.
I'm coding a simple application in Django to track cash operations, track amounts, etc.
So I have an Account Model (with an amount field to track how many money is inside) and an Operation Model(with an amount field as well).
I've created a model helper called Account.add_operation(amount). Here is my question:
Should I include inside the code to create the new Operation inside Account.add_operation(amount) or should I do it in the Views?
And, should I call the save() method in the models (for example at the end of Account.add_operation() or must it be called in the views?)
What's the best approach, to have code inside the models or inside the views?
Thanks for your attention and your patience.
maybe you could use the rule "skinny controllers, fat models" to decide. Well in django it would be "skinny views".
To save related objects, in your case Operation I'd do it in the save() method or use the pre_save signal
Hope this helps
Experienced Django users seem to always err on the side of putting code in models. In part, that's because it's a lot easier to unit test models - they're usually pretty self-contained, whereas views touch both models and templates.
Beyond that, I would just ask yourself if the code pertains to the model itself or whether it's specific to the way it's being accessed and presented in a given view. I don't entirely understand your example (I think you're going to have to post some code if you want more specific help), but everything you mention sounds to me like it belongs in the model. That is, creating a new Operation sounds like it's an inherent part of what it means to do something called add_operation()!

Most Pythonic double dispatch for extracting View information from Model

I'm coding a desktop app with Python and Qt, using PySide. I need to display a tree view in which top-level items are objects of different type than their children. Specifically, a top-level item is a Git repository, whereas its children are directories in the work tree.
For a repository, I want to show its path and currently checked-out branch. For a directory, I just want to show its name.
Right now, I do this by having my QAbstractItemModel descendant use isinstance on the underlying model object (retrieved from internalPointer() method) and decide how to format the resulting string.
I was wondering whether there was a more Pythonic (or just less clunky) way of doing this kind of double dispatch.
What I don't want to do is define a method for this purpose in my model classes for Git repo and work tree file, because I feel this would violate SRP.
Any thoughts or ideas are most welcome. Also, if anyone can think of a less clunky title for this question, let me know ;)
If you were ok with each Model class having a function containing View code, then you could just call those functions. To separate the Model/View code without using isinstance, this sounds like a case for the Visitor pattern, as described in this SO answer, and as used in the ast module.
Basically, each Model class has an accept() method that takes a Visitor object. The accept() method for a repository calls the visit_repository() method of that Visitor object, passing self (which is the Model instance). Similarly, the accept() method for a directory calls the visit_directory() method of that Visitor object, passing self. The visit_repository() or visit_directory() method then has access to the Model instance and knows its type and can show the appropriate view. This separates the View code (in the Visitor object) from the Model code (in the Model class).
*Note: instead of using different function names (visit_repository() vs visit_directory()), you can use multimethods, e.g., this SO answer about multimethods in Python.

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.

Categories

Resources