Converting existing python classes into Django Models - python

I have a small program with a command line interface that uses a number of python classes with thorough implementations. I want to scrap the command line interface and wrap the app within a Django app, but I'm just learning Django and I'm unfamiliar with the conventions.
I have a number of classes, in-memory storage structures, getters/setters etc and I'd like to convert them into Django models so that I can persist them to the database and interact with them around the django app. Is there a general approach for doing something like this?
Should I just inherit the django.db.models.Model class in my existing classes and set them up for direct interaction? Or is there a better, more general/conventional way to do this?
I would like to be able to use all of this code in other apps, not necesarilly Django ones, so I don't really want to modify my existing classes in a way that would make them only work with Django. I thought of creating the models separately and then a sort of middle-man class to manage interaction of the actual in-memory class with the django model class, but that just seems like more places I have to make changes when I extend/modify the code.
Thanks for any help ahead of time...

Personally, I would modify your existing classes to extend models.Model and maintain separate versions of these classes for use outside of Django.
This will keep your classes lean and maintainable within their respective environments.
You could also create a new class that extends both models.Model and your python model through multiple inheritance. However this will result in duplicate fields for the same data.
If you would like, post an example Model as a new question and tag me in a link to it here, and I can help you convert it.

One of greatest django strengths is its ORM, if you want import i recommend you use it, and yes you would probably need rewrite the part that interacts with the database, but if you already have isolated this functions in a Models folder~classes, the modification won't be really hard
Although in your case i would recommending checking out Tornado/Aiohttp Since looks like you are just trying to create a interface for your functions

Related

Python/Django - Where do I have to make methods that perform like DML?

'Methods that perform like DML' means methods that change data in the database.
Is there a standard or guideline for that?
Below are my own guesses.
Collect all functions in file of which name is like 'data_access.py'
Contain functions in each class of models.py
There is no standard. No one will blame even if I make them in views.py
Above all are wrong.
A common philosophy in Django is "fat models, thin views", so preferably you would put as much of this DML functionality as functions on your model classes. Since models.py already defines the structure of your data, it makes sense to put functions that manipulate your data in the same file as much as possible.

Why is factory_boy superior to using the ORM directly in tests?

I don't see why factory_boy is preferred over creating ORM/model instances directly in Django tests. And the factory_boy website does little to explain the benefits of using it.
It makes sense as an alternative to fixtures, which are difficult to manage, are slow, etc. etc.
But, why not just create model instances as needed for the tests?
If factory_boy completely replaced writing to the db, then fine, I think it'd be very useful in this case, but the the factory boy created django model instances still interact with the database.
Another potential benefit is the support for sequences, but it is not hard to create sequences / sample data without the need for factory boy.
All in all I'm seeing virtually no benefits in using factory boy, vs creating objects/model instances directly.
I hope I'm missing something glaringly obvious!
Yes, you can prepare your test data by using django ORM directly. But there are advantages of using factories and factory_boy specifically, here are some of that I remember and use:
your model factories are defined in a nice, clean and readable manner:
class CasesFactory(factory.Factory):
FACTORY_FOR = models.Case
number = factory.Sequence(lambda n: '1021-{0}'.format(n))
create_date = datetime.datetime.now()
another benefit of this class-based approach is the ability to create SubFactories
also you can easily define factories for different kind of relationships: ForeignKey, reverse ForeignKey, ManyToMany (documentation)
neat DjangoModelFactory class
Sequences (as you've mentioned) helps make the data more "dynamic". Imagine handling it yourself.
mute_signals decorator - sometimes while testing you don't want the signal to be dispatched
Basically, factory_boy is there to avoid writing "helper" functions for generating test data. Instead, it introduces a nice and easy-to-use interface to it.
Ask yourself: why reinvent the wheel is there is a tool specifically for the job?
Also see:
Testing and Django (Carl Mayer's presentation)

Getting and serializing the state of dynamically created python instances to a relational model

I'm developing a framework of sorts. I'm providing a base class, that will be subclassed by other developers to add behavior to the system. The instances of those classes will have attributes that my framework doesn't necessarily expect, except by inspecting those instances' __dict__. To make things even more interesting, some of those classes can be created dynamically, at any time.
I'd like some things to be handled by the framework, namely, I will need to persist those instances, display their attribute values to the user, and let her search/filter instances using those values.
I have to use a relational database. I know there are some decent python OO database out there, but unfortunately they're not an option in this case.
I'm not looking for a full-blown ORM too... and it may not even be an option, given that some of the classes can be created dynamically.
So, my question is, what state of a python instance do I need to serialize to ensure that I can deserialize it later on? Is it enough to look at __dict__, or are there other private attributes that I should be using?
Pickling the instances is not enough, because I'll need to unpickle them to search/filter the attribute values, and I'm afraid it's too much data to do it in-memory (instead of letting the database do it).
Just use an ORM. This is what they are for.
What you are proposing to do is create your own half-assed ORM on your own time. Save your time for your own code that does things, and use the effort other people put for free into solving this problem for you.
Note that all class creation in python is "dynamic" - this is not an issue, for, well, anything at all. In fact, if you are assembling classes programmatically, it is probably slightly easier with an ORM, because they provide reifications of fields.
In the worst case, if you really do need to store your objects in a fake nosql-type schema, you will still only have to write your own backend driver if you use an existing ORM, rather than coding the whole stack yourself. (As it happens, you're not the first person to face this - solutions exist. Goole "python orm store dynamically created models" and "sqlalchemy store dynamically created models")
Candidates include:
Django ORM
SQLAlchemy
Some others you can find by googling "Python ORM".

How to structure complex Django project?

I have a Django project which is getting more and more complex. I started off with the traditional files: models, views, and forms.py. The issue I have right now is that those files are getting bigger and bigger and I'd like to break them into manageable parts. What are the best practices around that?
In addition, I am wondering if it is best practice to add class method to a model in Django? For instance, I have a Vote class on which I would like to add methods to get the number of votes for a specific user, content, etc?
I find refactoring can really help. Are there a lot of similar views that just have different templates or querysets? Make a more generic view that accepts multiple template names, records, etc.
Anything that requires extensive calculations gets moved to a utils.py in the same directory.
Class methods are for actions that affect a single record; managers are for dealing with filtering records or creating a record.
If you're already taking the step of making separate models, views, etc. folders and breaking views and models into separate files, that suggests to me that you could separate them out into separate apps. I like that as an option much better.
I certainly use class methods, and I have found that where there are similar operations to be performed on classes, it is possible (and easy) to factor the classmethods into base classes (use the self parameter of your class method to write generic code).
Probably the best way to manage broken-up views, etc is to replace each file you want to break up with its own package, and put whatever you need to (if anything) into that package's __init__.py module.
On using model managers vs class methods. doing it this way, your code is easier for others to read, and you can combine this kind of code with other filter/select_related/order_by. Below is a simple example, but as the logic gets more complicated Managers make a great addition to your setup and for very little code, give you a lot of good connective tissue in your app.
I agree with Jordan that you may need more than one app and if you have a large code base now, the lines to break everything up by should be more apparent to.
class VoteManager(models.ModelManager):
def by_user(self, user):
return self.filter(user=user)
def by_content(self, content)
return self.filter(content=content)
class Vote(models.Model)
user = models.ForeignKey(User)
content = models.ForeignKey(Content)
...
objects = VoteManager()

Converting Python App into Django

I've got a Python program with about a dozen classes, with several classes possessing instances of other classes, e.g. ObjectA has a list of ObjectB's, and a dictionary of (ObjectC, ObjectD) pairs.
My goal is to put the program's functionality on a website.
I've written and tested JSON encode and decode methods for each class. The problem as I see it now is that I need to choose between starting over and writing the models and logic afresh from a database perspective, or simply storing the python objects (encoded as JSON) in the database, and pulling out the saved states for changes.
Can someone confirm that these are both valid approaches, and that I'm not missing any other simple options?
Man, what I think you can do is convert the classes you already have made into django model classes. Of course, only the ones that need to be saved to a database. The other classes, as the rest of the code, I recommend you to encapsulate them for use as helper functions. So you don't have to change too much your code and it's going to work fine. ;D
Or, another choice, that can be easier to implement is: put everything in a helper, the classes, the functions and everything else.
SO you'll just need to call the functions in your views and define models to save your data into the database.
Your idea of saving the objects as JSON on the database works, but it's ugly. ;)
Anyway, if you are in a hurry to deliver the website, anything is valid. Just remember that things made in this way always give us lots of problems in the future.
It hopes that it could be useful! :D

Categories