Where to put a Mixin that's used by multiple apps? - django

I'm sorry if this is a basic question, but I have a mixin I want to use in multiple apps.
Is there a best practice on where this mixin should go?
Thanks

You should create a file mixins.py in your utils/ folder and use it your apps.

I would create an app which includes the Mixin and rely on this app in all those multiple apps which should use the Mixin. A short example as i don't know the purpose of your Mixin:
If you want to write a Mixin which is related to authentication i would recommend to create an app call myauth (where my should be some other prefix)- put the Mixin there and all other apps will rely on myauth in this case. myauth might later also include other pieces related to authentication.
If this Mixin will be the only thing you want to reuse in other apps you might just create a non specifiy purpose app like mygeneralpurposelibs and put it there together with stuff necessary for completely different purposes.
I prefer the topic related apps like myauth instead of the lib buckets. As usual the final app structure relies on your specific needs.

Related

emberjs mixin vs extend

I am thinking of using dockyard validations in my project
I have options as to how to use the Validations-Mixin from dockyard
Approach 1 to have a BaseController which will mixin this Validations-Mixin and get the functionality in all controllers
Approach 2 use the Mixin directly.
Pros of 1
no need to import ember-validations in every file and mixin manually , and I get the functionality of validations in all the controllers.
Cons of 1
Validations might not be required in all the controllers , may be it's required only in 50% of the cases, also might reorder the way existing controllers add the mixins.
Pros of 2
Simple, only who need the functionality will import and use it.
Cons of 2
importing in each file where required and adding the mixin.
I think you should use that mixin directly. Why?
Because there is no need to extend it in every controller in your app. Extending mixins is a way to obtain shared functionality between controllers that share that functionality. I am pretty sure that not every controller in your app needs validation.
From my experience I can say that only some percent of controllers use validations (it depends on the app, but it's just a rough mean value). Import the mixin where it's needed.

How to test view mixins in Django REST Framework?

In my Django site I use Django REST framework. To not repeat myself, I created a couple mixins to simplify writing my view sets (here is an example of a similar style of mixin).
My question is how do I go about testing such a mixin? If it was a regular view exposed on some URL, I would use APITestCase provided by the framework, but since my mixin is not a standalone object and needs to be inherited from to be actually useful, this way of testing is not applicable.
Is there some way to mock the rest of the view? Or do I have to create a dummy application using this mixin and do integration tests?
You should test Django REST Framework view mixins the same way that you should test standard Django view mixins. You test it when attached to a view or you mock up all of the parts of a standard view that it would rely on.
You should be able to test mixins when attached to views in the same way that you would test standard views, because mixins should behave consistently in ways that are testable. You may need to create test views for each case that the mixin works with, which is what we had to do with DRF JSON API when creating the tests.
In the case of Django REST Framework Bulk, the best way would probably be to create a view that has the mixins attached to it, and test that it responds as expected. For the bulk mixins, lets assume that the following needs to be tested:
Single object POST still works
Multiple object POST on the list
Multiple object PUT on the list
Multiple object PATCH on the list
Multiple object DELETE on the list
This would require at least five tests, most likely split up for what they are testing. You would also need to make sure that the tests cover the hooks that are also being called, as well as any side effects that are expected.
The Python unittest.mock module helps a lot with mocking views (if you want to do that) and allows you to determine if methods (such as the hooks) are called.

The true meaning of django project and individual apps in it

What really is the true meaning of django project and individual apps in it?
I mean - AFAIK you cannot create a project and live entirely in that project you created, you have to create an app in that project to be able to actually do something in django. Please correct me if I'm wrong.
Now what should really be the structure of a django project? I'm writing an e-shop. Let's say my project is named foo:
/foo
/foo
/settings.py
/templates
/urls.py
/wsgi.py
/shop
/__init__.py
/admin.py
/models.py
/tests.py
/views.py
and do everything entirely in /foo/shop/, but I edit urls.py inside /foo/foo/ etc.
I was following the Django Book, but I've begun to gain that strange feeling that /foo/foo/ is just for a main folder "stitching the thing together" but individual stuff should be done only in /foo/shop/, but not limited to. Preferably in /foo/web/, /foo/products/, /foo/forum/, /foo/controlpanel/, /foo/shop/, /foo/helpdesk/, /foo/backoffice/ etc.
Is that correct? Should I put everything products-related in /foo/products/, that including storage management, shipping, dealers, prices etc., then put management of those products (from the employee side) to /foo/backoffice/, which will serve as some sort of "django.contrib.admin" for this? Is that correct? Then if I want to host multiple instances of this (with completely separate databases and stuff) for multiple customers, should i only create a barebone project, that will put these things together, to configure the settings and then just move individual components in some sort of central repository and call them back in the project via INSTALLED_APPS? Because that would be cool as hell! I mean - making all the changes globally, not touching users data and configuration, unless necessary (adding columns in models and such). Is this how django is really supposed to be used? Or am I completely off the track and do things ENTIRELY wrong and this paragraph just doesn't make any django-sense?
I'm relatively new to this. I've been using PHP before and even though Django was a pain-in-the-ass to get basic grip of, I don't regret that and plan to deprecate and make offline any PHP project I created to date and replace them all with django. Well - where it makes sense and is not a single-purpose site. Not only because Django is awesome and versatile, but i cas I can scale it easily as well…
So… How should I really design Django projects, apps, and how to use them in production, providing them to multiple customers?
Thank you!
I mean - AFAIK you cannot create a project and live entirely in that project you created, you have to create an app in that project to be able to actually do something in django. Please correct me if I'm wrong.
You can do plenty of things on just a project, but you need an app for models to be auto discovered.
For example, I have a project with just this in urls.py:
class Homepage(generic.TemplateView):
template_name = 'homepage.html'
def get_context_data(self):
context = cache.get('homepage')
if not context:
management.call_command('reset_cache')
context = cache.get('homepage')
return context
urlpatterns = patterns("",
url(r"^$", Homepage.as_view(), name="home"),
)
You guessed it, it's a really basic website.
and do everything entirely in /foo/shop/, but I edit urls.py inside /foo/foo/ etc.
I was following the Django Book, but I've begun to gain that strange
feeling that /foo/foo/ is just for a main folder "stitching the thing
together" but individual stuff should be done only in /foo/shop/, but
not limited to. Preferably in /foo/web/, /foo/products/, /foo/forum/,
/foo/controlpanel/, /foo/shop/, /foo/helpdesk/, /foo/backoffice/ etc.
Well, you should define /foo/shop/urls.py, and import it from /foo/foo/urls.py ie.:
urlpatterns = patterns("",
url(r"^shop/", include("shop.urls")),
)
The point is to make your apps more convenient to reuse in other django projects.
Is that correct? Should I put everything products-related in
/foo/products/, that including storage management, shipping, dealers,
prices etc., then put management of those products (from the employee
side) to /foo/backoffice/, which will serve as some sort of
"django.contrib.admin" for this? Is that correct?
You should take a look at open source projects and see how they divided that.
According to the directory tree that you represented, you seem to have understood the point, but your statement seems fuzzy so I'll attempt to clarify it.
Apps are generally oriented around models. So if I make a product app it will probably contain:
Product model,
Product list, edit, create, delete and detail view
urls for the views,
Product admin,
tests for Product and views,
other things which are used by other django apps like product/admin.py would be used by django.contrib.admin, but also external apps like django-autocomplete-light would use product/autcomplete_light_registry.py and django-rules-light would use product/rules_light_registry
Then if I want to host multiple instances of this (with completely
separate databases and stuff) for multiple customers, should i only
create a barebone project, that will put these things together, to
configure the settings and then just move individual components in
some sort of central repository and call them back in the project via
INSTALLED_APPS?
There are many ways to do SaaS with django. But I agree that the easiest and most convenient is to maintain generic apps and build a project per customer that reuses (and eventually override parts of) these apps.

Django design patterns for overriding models

I'm working on an e-commerce framework for Django. The chief design goal is to provide the bare minimum functionality in terms of models and view, instead allowing the users of the library to extend or replace the components with their own.
The reasoning for this is that trying to develop a one-size-fits-all solution to e-commerce leads to overcomplicated code which is often far from optimal.
One approach to tackling this seems to be using inversion-of-control, either through Django's settings file or import hacks, but I've come up against a bit of a problem due to how Django registers its models.
The e-commerce framework provides a bunch of abstract models, as well as concrete versions in {app_label}/models.py. Views make use of Django's get_model(app_label,model) function to return the model class without having to hard-code the reference.
This approach has some problems:
Users have to mimic the structure of the framework's apps, ie the app_label and effectively replace our version of the app with their own
Because of the way the admin site works by looking for admin.py in each installed app, they have to mimic or explicitly import the framework's admin classes in order to use them. But by importing them, the register method gets called so they have to be unregistered if a user wants to customise them.
The user has to be extremely careful about how they import concrete models from the core framework. This is because Django's base model metaclass automatically registers a model with the app cache as soon as the class definition is read (ie upon __new__), and the first model registered with a specific label is the one you're stuck with. So you have to define all your override models BEFORE you import any of the core models. This means you end up with messy situations of having a bunch of imports at the bottom of your modules rather than the top.
My thinking is to go further down the inversion-of-control rabbit hole:
All references to core components (models, views, admin, etc) replaced with calls to an IoC container
For all the core (e-commerce framework) models, replace the use of Django's base model metaclass with one that doesn't automatically register the models, then have the container explicitly register them on startup.
My question:
Is there a better way to solve this problem? The goal is to make it easy to customise the framework and override functionality without having to learn lots of annoying tricks. The key seems to be with models and the admin site.
I appreciate that using an IoC container isn't a common pattern in the Django world, so I want to avoid it if possible, but it is seeming like the right solution.
Did you look at the code from other projects with a similar approach?
Not sure if this way covers your needs, but imo the code of django-shop is worth to look at.
This framework provides the basic logic, allowing you to provide custom logic where needed.
customize via models
eg see the productmodel.py
#==============================================================================
# Extensibility
#==============================================================================
PRODUCT_MODEL = getattr(settings, 'SHOP_PRODUCT_MODEL',
'shop.models.defaults.product.Product')
Product = load_class(PRODUCT_MODEL, 'SHOP_PRODUCT_MODEL')
customize via logic/urls
eg see the shop's simplevariation-plugin
It extends the cart-logic, so it hooks in via urlpattern:
(r'^shop/cart/', include(simplevariations_urls)),
(r'^shop/', include(shop_urls)),
and extends the views:
...
from shop.views.cart import CartDetails
class SimplevariationCartDetails(CartDetails):
"""Cart view that answers GET and POSTS request."""
...
The framework provides several points to hook-in, the simplevariation-plugin mentionned above additionally provides a cart-modifier:
SHOP_CART_MODIFIERS = [
...
'shop_simplevariations.cart_modifier.ProductOptionsModifier',
...
]
I worry that this explanation is not very understandable, it is difficult to briefly summarize this concept. But take a look at the django-shop project and some of its extensions: ecosystem

how to make interaction between different django apps in a single site?

I have just learnt about Django apps. I want to know that within one site, if I make different apps. like, users, profiles, polls, blogs,comments, jobs , applications then how can I manage them to make them intereactive? And is it how the concept of app should be? I want to have things loosely coupled that's why asking? Rails work on the way of REST, so do Django support that also with the use of apps? May be my questions seems a bit ambiguous because I am new to django and some of my concepts are still messed up.
Please tell what ever you know.
The general idea is that apps should be as loosely coupled as possible. The goal is to have completely self-contained functionality. Now, of course, that's not always possible and many times it even makes sense to bring in functionality from another app. To do that, you simply import whatever you need. For example, if your "blogs" app needed to work with your Comment model in your "comments" app you'd simply add the following to the top of the python file you're working in:
from comments.models import Comment
You can then use Comment as if it were defined right in the same file.
As far as REST goes, Django's views are much more fluid. You can name your view whatever you like; you need only hook it up to the right urlpattern in urls.py. Django views can return any content type, you just prepare the response and tell it what mimetype to serve it as (the default is HTML).