architecting a django app that has a lot of common features between apps

为君一笑 提交于 2019-12-11 13:24:12

问题


I have a high level question about how to architect this app in django.

I have a few models that will undergo similar operation that will be performed on them by a view (like create, edit, save etc). You will also have some operations that are unique. Many of these operations are the same and I do not want to repeat the code. These models will have a few fields that are common among all of them, and they will also have field that are unique. What is the best way to design this?

The different models will be different apps. For example, the model can be school, church or restaurant. Therfore, you will have three apps. I suppose these models are subclassed from an abstract class. The views will also have some operations that are the same for all these three apps. Not sure how to write a common set of code, and have these three apps inherit something and then customize if needed. I just need some pointers/direction.

Edit: These models have a few common fields, but that is where the similarity ends. You could have models for schools , events or news articles (as you can see they can be completely different from a human point of view). I am going to add or remove these models as necessary, therefore, I must have separate apps. It almost seems like you need to create something that is common that you'd call in all these apps, but this common set exists for the model and views (almost need a framework that does all this I think).


回答1:


This is more of a conceptual answer.

If the models are very similar, I think that they should belong in the same app. My reasoning is as follows. An app, again in my opinion, is a set of related data as well as business logic associated with that data and possibly even some logic as to how that data should be presented. So if the models are very common, it would seem that the data is somewhat related and therefore should in the same app.

However in my experience some apps can grow where I've had more then 20 models in a single app. That can get very difficult to manage in one models.py file, therefore I like to break models into a package. So then the structure of the app might look like:

project/
  manage.py
  project/
    __init__.py
    settings.py
    ...
  app/
    __init__.py
    ...
    models/
      __init__.py
      ...

The only thing is that if you do this, then you have to import all of the models in the model's __init__.py file and include them in __all__ variable. That way even though the models are structured as a package, in the rest of the code you can use them as a module.

The advantage of this approach is that you models are modular, which makes it much easier to maintain and it keeps relevant data in a single place.


As for business logic, I think inheritance should take care of many issues. You can always inherit from multiple classes. That allows you to make a set of base classes/models with a specific set of functionality in each and then just inherit from the appropriate base classes for your models. That will allow you to reuse as much of the code as possible.

Another approach is to use meta-classes. The idea is that you define a class which builds an instance of a different class. Example:

class FooMetaClass(type):
    def __new__(cls, name, bases, dict):
        # do some logic
        return super(FooMetaClass, cls).__new__(cls, name, bases, dict)

class FooClass(object):
    __metaclass__ = FooMetaClass
    ...

So the idea is that you can include some setting attributes in FooClass, and according to those attributes and possibly even their values, the meta-class can build out a customized instance of that class. At this point you can even generate dynamic things!

I found this approach useful a couple of times however in most cases I think that sub-classing should be more then enough.


For presentation, class based views are perfect. During this years DjangoCon, Kenneth Love gave a very good talk on class based views. Here you can see the slides: https://speakerdeck.com/u/kennethlove/p/views-can-be-classy and hopefully the video will be published soon. The big idea is that a class based view is identical to a function based view except the way it is structured.

I know in many of my projects, many of my views are pretty much identical. There is something going on in the beginning of the view, which is very similar across many views. Then there is some middle/meat section of the view, which is usually what is unique to each view. And then there is the end section of the view where I construct the context dictionary and return the response. So what I and many other developers end up doing is having a billion helper functions, which we call in other views to do certain repetitive tasks. This approach however makes code harder to read, sometimes introducing unnecessary abstractness since you have to pass many parameters to the helper functions, and finally just does not feel right.

This is where class based views come in. They do exact same thing as a function based view, except they break up the view into multiple function calls. So one function can be responsible for getting the object, another for constructing the context, and so on. Then when all of these functions are combined, then pretty much execute identical code to as what you might have in a function view. This however brings one major advantage. You can inherit views. So you can have one base class view for doing task a, and another for doing task b, hence you can make another view which inherits from both classes, hence doing both tasks. Additionally, once you inherit from some base view, you can overwrite whatever function base class defined, therefore giving even more flexibility.

That is very useful design pattern for doing common tasks for many similar views, yet minimizing the amount of code to write.


Hopefully this gives you some ideas as to how structure a project/app.



来源:https://stackoverflow.com/questions/12418182/architecting-a-django-app-that-has-a-lot-of-common-features-between-apps

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!