decoupling django apps - best practice to layout a project - django

I'm working on a project that has several apps, and want to include a news app for news stories.
However, I'd like to link news stories to objects in my custom app, but use an open source news app to run the news.
At the moment I've simply hacked the chosen news app to add in a ForeignKey relationship with my model.
i.e. a widgets app, with a widget model
then a news app with the entry model linked directly to my widget model
Is there a better way to do this? because if I want to update the news app with the latest version of it, it'll obviously overwrite my hack.
I could have the link from my custom model, but the workflow should really be
Add news article
choose a widget to link it to
NOT
Add a news article, save
Find the widget to link it to
Link back to the news article

I think you could have a model which inherits from the model in the external app. Something along the lines of:
MyNewsArticle(ExternalAppNewsArticle):
object = models.ForeignKey(MyObject)
As long as you're adding things rather than dropping things, this should work. You have to be careful if the model from the external app has any Custom Managers declared though, because by default Django will not inherit them. You might need to declare them again in your own model.

Related

Django: Last modified by and created by user automatic saving

The age-old question: How can I automatically save last_modifed_user in django models?
I found in several places this general process how to do it using thread local. I'm hesitant to simply implement it that way because I'm not entirely sure of the consequences it has and because all these posts are old.
Is using thread local still the "recommended" way of doing this in django 3? Or does django3 have a better options of doing it?
No, this hasn't changed. Simply because separation of concern is an architectural principle of MVC (model-view-controller), which is also how Django (model-view-template) and most web frameworks with ORM are architected. Models know nothing about the request, it's not available (and in many cases there isn't a request at all when a model is saved, think of management commands or regular tasks running in the background).
The alternative to thread local is to make sure you implement it yourself in the controller layer (view layer in Django):
Create a view mixin that you can mix with all the generic views that use the ModelFormMixin to save the user into the model (ModelFormMixin.form_valid()). Or combine it with a form mixin where the user is passed to the form (FormMixin.get_form_kwargs()) and saved when the form is saved (ModelForm.save()).
Create a ModelAdmin mixin that does the same when saving a model in the django admin site.
This of course means someone on your team may forget to do it when creating new views and forms. The link you posted contains an answer as to the advantages and disadvantages of using thread local.

Adding a new section in Mezzanine CMS (Django) admin

I'm totally new to Mezzanine CMS. I got handed a site to work with and so far I've been able to do all the changes without problem. I've run across a problem in which they want a new section in the home page. I go to the admin section to edit the home page, but there is no extra content field.
On the home page, I see 4 sections "content" "priorities" "testimonials" and "clients". I would like to have another "content" area as a 5th section. How do I go on and add this section? I'm totally new to Django but would be appreciative if someone could explain or point in the right direction.
Here is a link to an image for reference.
https://imgur.com/a/sUKOtvS
Thanks in advance
The homepage content would be backed by a Django model with attributes for the partners and testimonial fields. You'll need to find the Python class for this model in your code base (you could search for those field names), and you'll need to add a new attribute for the new section you need.
Django and Mezzanine have lots of different field types you can use for these attributes, so consult their respective documentation for how those work (Django's are a lot more comprehensive, so start there).
Once you've done that, you'll need to create a database migration for the new attribute - that adds the field to the database table that will store the actual content, again consult the Django documentation for how these work.
Finally you may need to add the new field to the Admin class, which is the Python class (similar to the model) that controls which fields appear in the admin interface, and how they appear. I say "may" as these generally appear automatically without any code, but if things have been modified to a certain extent, you may need to do this manually.

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).

Notification to user from admin

I am new in Django and don`t know the best way to realise next functionality in my project.
In my django project I have users with different roles. One of them is admin who can create project. I mean that I have model with fields (project_name, project_managers) which filled by admin. The managers of the project are users of the system, admin can choice some of them. After all how to show them notification in real time that they was managers of the current project. Is it makes by websockets or Jquery or something else. I need some ideas how to realise that with detail explanation if it possible.
You can use post_save signal to implement your notification functionality. This signal will be called once the model object is saved.

Where is recommended spot for storing admin customizations for Django contrib apps?

I want to add Django Sessions to my Django Admin, and I am following an SO post about this, but it is unclear where I store this code. Do I put it in an admin.py file? Under what directory?
In short, it doesn't matter. You can put the code into any of your apps' admin.py files. However, in situations like these I tend to use a generic app in my project, usually named something like utils, that exists for the sole purpose of housing code that doesn't belong to one specific app or could be used by multiple apps.
If you want to be more specific, you can create a sessions app in your project specifically devoted to this code and any other code related to session management for your project, or perhaps an existing app that is somewhat related. For example, I put customizations to the User admin in my accounts app that holds the UserProfile model.