Python, bad practice to have same name on classes - python

I have multiple files like this in a django app.
django-app
----views
-------app_one.py
-------app_two.py
-------app_three.py
Inside app_one.py i have code similar to this
class AppOne:
... some methods ...
class Data(AppOne, APIView):
def post(request):
class History(AppOne, APIView):
def get(request):
In app_two.py I would like to name my classes like this (Note the sub_classes have the same names as in app_one):
class AppTwo:
... some methods ...
class Data(AppTwo, APIView):
def post(request):
class History(AppTwo, APIView):
def get(request):
So, my question is this: This works fine, I can run the server etc. But is this a bad practice? Could I run into unexpected results because of this?
The reason I want these specific names is because I use them inside Django admin for a permissions thing.

Views don't matter in the admin at all, so that's beside the point.
No, you shouldn't bump into any trouble; after all Django doesn't really care about your view classes' naming, it just cares about how they're hooked up in your urls (or if you're using DRF, based on APIView, your API router).
There's also nothing stopping you from inheriting things cross-app (after all, apps are just Python packages that are registered with Django) if that leads to less code and/or makes sense for you.

Related

Using Django Views and Forms without a Models based Database

I am kind of new to Django (been writing Python for a while now) and I was wondering if it is at all possible to use the Views and Forms framework in Django without having the need for a database or the use of Models.
The content is dynamic, and gets populated into a dictionary each time the user launches the website. So I would like to leverage the Django Views and Forms but passing through the details from the dictionary and not from a Model Class (Database)
I hope I have explained myself correctly.
So to add onto this then.
If you had the following for a Models based class:
class TestClass(models.Models):
var1 = models.CharField(....)
class DetailView(generic.DetailedView):
model = TestClass
How could I use the DetailView class (Or any other django based View framework with a class based dictionary like this:
class TestObj(object):
def __init__(self):
self.var1 = []
testdict = defaultdict(TestObj)
testdict['test'].var1 = ['blah']
Do I just use the dictionary in the model field under the DetailView class ?
please excuse me if I have anything typed incorrectly.
Thanks
It is totally possible.
However, if you decide not to have a database you will lose a chance to use many contrib features (like accounts, backend). From the "empty" project (made with django-admin startproject) you will need to remove most of INSTALLED_APPS, MIDDLEWARE, context_processors in TEMPLATE, set DATABASES to an empty dict() (see the comment from #spectras), maybe some other settings tinkering on top.
Upd: (Since you modified your question significantly, here are more details)
Using django.db.models doesn't make much sense without a database (pay attention on db in the path to models package). Some generic views (like DetailView) are made to spare your time when working with models, so using them will not make much sense neither.
If you don't need to save any of TestClass instances and their lifetime is limited to generating a response to a single user request, you should be fine without using django models at all. Using TemplateView will be sufficient.
class TestClass(object):
def __init__(foo, bar):
self.foo, self.bar = foo, bar
class MyView(TemplateView):
template_name = 'my_template.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['my_object'] = TestClass(foo="hello", bar="world")
return context
In my_template.html:
{{ my_object.foo }} {{ my_object.bar }}

django: where to put recurring query on list of model objects

I have Product as a model.
I am refactoring some code, and there is a recurring query spread all over the code base which needs replacement.
So I'd like to centralize this query, in order to encapsulate its logic.
I'd like something like
<an_object>.get_uncompleted_products(products);
In this case, preserving existing code, products is already a result of a query (products = Products.objects.filter(filter_expression))
This is just a convenience question, I know a possible answer, but where would you put get_uncompleted_products(), what could be a good"django-way" solution?
I was initially wanting to put it on the Product model. But I was thinking Product methods to work directly on a single model reference, thus the signature would need to be:
class Product(models.Model):
#classmethod
get_uncompleted_products(list)
I am not sure why this gives me the feeling to be not so appropriate. A possible alternative would be to put it into a utility module. I could also have it in the view module but it seems it's used profusely in other views as well so I'd prefer somewhere more generic.
I guess the 'django way' would be to define it as a custom manager method, instead of class method, which can be shared between different models with composition instead of inheritance in case of class methods.
from django.db import models
class ProductQuerySet(models.query.QuerySet):
def get_uncompleted_products(self):
...
class ProductManager(models.Manager):
def get_queryset(self):
return ProductQueryset(self.model, using=self._db)
def get_uncompleted_products(self):
# defined twice to resolve queryset chaining issue with custom managers
return self.get_queryset().get_uncompleted_products()
class Product(models.Model):
...
objects = ProductManager()

Should I be using controllers.py or #staticmethod in Django?

The person on our team who initially taught us django (and has subsequently left) utilized a controllers.py file for helper functions. A lot of these functions are directly related to classes. I prefer to use #staticmethod to house these helpers with the classes they're related to. For example, rather than doing this:
# controllers.py
def process_entry():
# do some exciting stuff that might not have to do with an instance
Called like this:
from myapp.controllers import process_entry
process_entry()
I'd prefer this:
# models.py
class Entry(models.Model):
name = CharField...
# some other fields
#staticmethod
def process_entry():
# do some exciting stuff that might not have to do with an instance
Called like so:
from myapp.models import Entry
Entry.process_entry()
Is there a preferred, standard way to deal with situations like this or is it just personal preference? Does anyone else utilize a controllers.py file? What goes in there?
Thanks.
EDIT:
Possibly a better example, commissions.
# models.py
class Commission(models.Model):
check = ForeignKey
payment = ForeignKey
# other fields
class Check(models.Model):
# fields
class Payment(models.Model):
# fields
Any time a Check or Payment instance is modified an adjustment as to be made to any related Commission instances or any time someone wants to manually run commissions, they can do so. So where should run_commissions() go? I prefer this, but apparently this shouldn't be encapsulated in a data-related model?
# models.py
class Commission(models.Model):
check = ForeignKey
payment = ForeignKey
# other fields
#staticmethod
def run_commissions():
# do stuff
Static methods are used for grouping related functions in one class (mostly for factory methods), beside that, there is no difference between static method and function.
BUT. In your example you are assigning behavior to DATABASE model. DATABASE models are not LOGIC models, and you should separate them from your app logic. Anyway, controllers is also a bad name in that matter.
I'm not sure what process_entry does, but if it's only changing one Entry entity, then it can be named: Entry.process(), but NOT Entry as DB model! just another Entry class. However if that function does more than just changing Entry, then it shouldn't be assigned to Entry entity, but made as a service function.

A lot functions in Django Model, way to separate it?

I got huge Django App with huge amount of sub-applications. Currently, i'm working on reworking of models in one subapp, so i got a... problem.
I have huge amount of separated ugly functions to work with model. Basicly, it is a someting like:
def get_some_things(...):
def postprocess(...):
pass
def preprocess(...):
pass
preprocess(...)
x = MyModel.objects.....get(1)
return postprocess(x, ...)
And i got A LOT of functiongs like this and it's really ugly! And it's ugly used in current code(like DatabaseAccessor.get_db().django_kitty().get_some_things(...)). So, my idea was to make developers able to use these functions like this:
MyModel.get_some_things(...)
Or even like this:
MyModel.objects.get_some_things(...)
But! I got soo many functions so i can't write it inside model.py. So, i got few ideas:
Create model_mymodel.py and define my model with all functions inside it and static functions. But... I'm not sure, do i need to put it in model class?
Create mymodel_manager.py and create model manager for mymodel, define functions here. But... some of my "functions" should return just dicts, lists or even numbers. I wonder, is it ideologically wrong to make model manager be able to return something except the QuerySet?
Override __getattr__ of the MyModel class and dynamicly load modules like functions_common.py, functions_things.py etc, store gathered functions into dictionary and call needed?
If your models require a lot of unique methods, having huge model definitions is the price you pay. If for some reason you do want to split the functionality to other files (or, for something actually useful, share common functionality) you could use a mixin approach:
#mymodel.py
class MyModelMixin:
def django_kitty(self, ...):
pass
def postprocess(self, ...):
pass
def preprocess(self, ...):
pass
#models.py
from mymodel import MyModelMixin
class MyModel(models.Model, MyModelMixin):
pass
Regarding your own suggestions:
1 - If you want separate files per model, you could use this approach:
myapp/
models/
__init__.py
from mymodel import MyModel
mymodel.py
Beware that you would need to explicitly set the app_label for each model:
#mymodel.py
class MyModel(models.Model):
...
class Meta:
app_label = 'myapp'
2 - The return value type of manager methods is irrelevant. The distinguishing point of managers and models is to separate table and row level functionality respectively.
3 - Sounds like unnecessary magic, overriding Model.__getattr__ is a painful task.
Sounds like option 2 is the way to go.
There is nothing wrong with a model manager method not returning a QuerySet.
The guiding principle I use for model functions versus model managers is this: I use method functions on models regularly as long as the objective is to act on a single model object. However if my use case required me to handle multiple objects of the model and meets my DRY incentive, I would use a model manager for that.

Pyramid/Pylons Framework - opinion on how am I using 'helpers' to accomplish certain tasks

In pyramid, I have created a 'helpers' functionality similar to that in pylons.
one particular function in my helpers.py file is like this:
from pyramid.renderers import render_to_response
def createBlog():
## lots of code here ##
return render_to_response('blog.mako', {'xyz':xyz})
And then in my other applications I can import helpers and do something like the following in my templates:
${h.createBlog()}
which creates a blog on my page. But I am just wondering is this a good way of using helpers to create "module" style plugins that I can easily use anywhere in my projects. Or are there any flaws to this technique which I haven't really thought of yet?
Thanks!
It really depends on how much stuff you want to expose globally. Obviously anything you put into h is available throughout the application, whereas you could return the createBlog function just in the views you want it to be in. One little-known tidbit is that if you use class-based views, the actual class instance is available in the view as the view global variable. For example:
class Foo(object):
def __init__(self, request):
self.request = request
def createBlog(self):
return render('blog.mako'. {})
#view_config(...)
def myview(self):
return {}
Now in your template you can call render your blog using ${view.createBlog()}.

Categories