How to write reusable apps with customizable models in Django? - django

I want to make reusable apps, that allow for customization by the integrator.
An example is if I make a newsletter signup app with the bare minimum of storing email address, but the integrator later wants to add additional fields, like say a name. What is the things I need to do to allow for this easily?
I went down the path of swapping out the models, like Django's auth system does, but that didn't work well. Then I found swappable attribute in the Meta class and a package that does this, but both are not intended for external use.
The only way I can think of for the integrator to do is, allow them to provide custom forms by passing it into the view in the urls for instance.
url('^someurl/$', MyView.as_view(form_class=SomeForm), name="myurl")
Then have a secondary model, with foreign keys to the internal newsletter model, but this means a secondary table that needs to be joined.
Another alternative is to try Abstract models, but I'm not sure what the impact will be there.
So what is the Django/Pythonic way of solving this?

Related

Adding permissions to Django model without table

I'm working on some Django Rest Framework based project (quite expected API for some web-app). It has as traditional Django models, and some kind of model-like objects: they behave like Django models but don't store anything in DB. No tables, no content-types. When we ask them for objects, they goes to external API and forms resulting Queryset.
Now I need to build some role-based access system. To make the architecture clear and extensible, I want to make groups and permissions managable through the Django Admin interface. So, I guess, we need to put some permissions to DB and then we'll be able to add these permissions to user groups. After that, we'll check these permissions in DRF.permissions class. But since we have neither tables, nor content-types for these 'models', we can't add records to permissions table right now.
What is the right way to make this possible? Should I rebuild these 'models' through the metaclass with proxy = True? Or should I add a proxy layer above? Maybe I should add some dummy content-types by hand?

Django- how to establish relationships between different apps?

(Keep in mind that still a begginer to Django) I've been creating my first Django App for a while now. In it, I have a model that represents a geographical area. This means that each instance of that model has the purpose of representing a different area on the map. This app is OK.
I've added a 2nd app, a reusable app, to my project, called django-forms-builder, that can be found here:
https://github.com/stephenmcd/django-forms-builder
This app allows me to create custom forms, in the Django Admin, that work fine. But they are 'stand-alone'/'separated' from anything from my own app.
I would like to establish some connection, from these forms from the 2nd app, to the area model from my own app, so that, as a result, specific forms can be associated to specific areas on the map.
This is really confusing to me, as I've only ever used a single app. I've read the models.py file in the 'django-forms-builder' app, and they are abstract, so it seems establishing foreign key relationships between models is not doable here, therefore I feel completely lost with no clues to follow on.
So my question is how to establish a relationship between different Django apps? I feel like there might be a Django concept, some idea other than model foreign keys that I could learn to accomplish this, and that I simply don't know about.
You have non-abstract models there.
With those you should be able to bind a form to a specific 'location':
from forms_builder.forms.models import Form
class Location(models.Model):
...
form = models.ForeignKey(Form, related_name='locations')
This way you can create and relate a form to multiple locations (I guess/hope that's what you are after).

Disallow linking objects based on a rule

I have two models: Domain and Record. Many records link to a domain. The domains and records have their owners. I want to disallow users to create records in domains that they don't own. However they should be able to edit records if someone else (a superuser e.g.) created them and set owner to that specific user (even if they don't own a domain). This should work both for admin site and for API (rest_framework)
My question is - what is the simplest way to achieve this goal? Is there some django plugin that handles permissions for linking? Can I use model validators here (if so - how to distinguish if a new object is created)?
The problem here is that the Django Rest Framework and Django itself (via admin) are interacting only at the level of the models. In order to achieve your goal I would implement the following design:
Make the models aware of their owners and users. For that I would use django-audit-log.
Overwrite the default model Manager and build your logic in the create method, where I will query the user's attributes and throw appropriate exceptions.
Such a design shifts some of the business logic from the controller to the data model - there are some debates out there about the benefits and pitfalls of such an approach. But with the underlined constraints (Django admin and API) is the only common place where you could put it.
Is this what you are aiming for ?

django: Selecting a freign key from 2 models

I am developing a blog styled application. I want to implement something like custom tags. (Trying to do the tag app myself, so I can learn something).
So I want to be able to create tags in admin interface, and want to be able to assign the to either my Section or Article model. I wonder if that's possible to make an model which will give ability to chose object (e.g. article or section)
I was looking on django comments app, but I would like to do something more simple. Is that possible?
Have a look at generic relations. A generic foreign key enables you to have have a foreign key relationship without having to define the target model in the code.
But I'd recommend to use django-tagging, which is a ready-made generic django tagging application which provides you a lot of additional functionality and is pretty easy to integrate (it also works via generic relations).

How to implement non-database backed models in Django?

I have an existing Django application with a pretty typical model implementation that's backed by a database. My task is to change this model so that instead of fetching the information from a database, it now fetches it from a service (e.g., via HTTP). Because there is existing code which already makes use of this model, it would be nice to maintain the same model interface so that it continues to behave like a typical Django model.
This raises a few of questions:
Is it possible to do this without having to re-write the interface from scratch to make it look like Django's model interface? (This stackoverflow question would seem to suggest otherwise: Django MVC pattern for non database driven models?)
Would writing a custom manager for this model be an appropriate approach (or have I misunderstood the role of the manager)?
Due to the service-backed nature of the new model, caching will be much more important than before. Is this something that should be implemented at the model level?
Have a look at django-roa. From the sound of it, it might be exactly what you are looking for.