Can all Django applications add items to a base template - django

I'm writing a webpage in Django and I have a application called "Website". This application defines some basic views and general layout of the whole site part of which is the navigation bar.
As I add applications responsible for different functionalities I would like to have them add links to that navigation bar. The links should appear not only when using a view from a certain application but in all others as well. The problem here is how to arrange this without the "Website" app knowing about all the other applications?

All Django apps inside one project can be aware of each other. For example, if you had an app called links, you could use models and functions from links to create new content, then use that content in Website. You will need to import the information. For example, to use links from links in your Website views:
# Website.views
from links.models import Link
def myView(request):
links = Link.objects.all()
# do something with the links
context = {'links': links}
return render(request, 'webpage.html', context)
Please excuse my syntax and stuff, I haven't tested this or anything. I hope this explains what you mean. Feel free to ask more, I'll do my best to answer.

Related

Showing link in menu conditional on logged in status

Using Mezzanine it's easy to toggle showing or not showing of regular pages using the 'Login necessary' toggle.
I want use this toggle for a Link-type page, unfortunately it's not there. What's the best way to achieve the toggling effect in Mezzanine?
I probably can inherit from the Link class and do something like this
class LoginLink(Link):
login_required = models.BooleanField(_("Login required"), default=False,
help_text=_("If checked, only logged in users can view this page"))
and use LoginLink as the page type instead but I hope there is a better solution. A better solution would have the following:
No new page type
No messing with core Mezzanine
I'm pretty sure my proposed solution works (but I really don't like it). Is it possible to extend the Mezzanine Link type in such a way only my own Link type is visible in the admin?
I've found a solution that's pretty short and sweet. The nice thing is that the login_required is already available for all pages through pages_page so we don't have to do any database modifications. With this solution you lose the option to create the default link type but in my case that's a plus from a usability perspective. One Link type is sufficient. The code for my solutions is as follows and goes into admin.py
# Get the Mezzannine admin logic and the Link model
from mezzanine.pages.admin import LinkAdmin
from mezzanine.pages.models import Link
# Create a custom LoginLink, with the login_required code from the page.
from copy import deepcopy
class LoginLinkAdmin(LinkAdmin):
fieldsets = deepcopy(LinkAdmin.fieldsets) + \
((None, {"fields": ("login_required",)}),)
# Unregister and register the LinkAdmin
admin.site.unregister(Link)
admin.site.register(Link, LoginLinkAdmin)
Adding this should be copy and paste.
Edit
I later found that this is the preferred way in the documentation. However, this only seems to work in my dev environment and not in our production-like environment. Further searching led me to the Model Customization docs. I didn't get this to work but it gave me a new idea. Mezzanine overrides the standard admin.site functionality, as described in this comment in /mezzanine/boot/lazy_admin.py:
"""
Defers calls to register/unregister until autodiscover is called
to avoid load issues with injectable model fields defined by
``settings.EXTRA_MODEL_FIELDS``.
"""
So I've come up with yet another solution. I've put the code above in my urls.py after admin.autodiscover() and deleted it from admin.py. This is ugly but it seems to work.

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.

What is the right way to organize a Django Project?

I'm new to Django and I'm trying to wrap my head around how these apps are supposed to be organized. I have the following questions:
Are apps like divs that are generated separately?
Can we have apps within apps?
Can we have apps that when clicked on, change other apps with javascript?
Right now I just have one views.py file and it loads all of its content through different function calls.
So right now I'm faced with if I should break up my views.py into smaller apps.
Am I going about Django the correct way?
Are apps defined like the they are in picture below, or are apps supposed to act more like a page?
What if I want a header, breadcrumbs, and footer for all my pages? I'm super confused #.#
Apps have nothing whatsoever to do with divs. Django is not a CMS (although it can be used to create CMSs) and doesn't dictate the layout of your templates.
The usual way to handle different blocks on the page that need different logic to populate them is via custom template tags. James Bennett has a good writeup on this, although the syntax is rather out of date so refer to the first link for that.

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

Front-end prototype/skeleton in Django

Often I create a static html prototype/skeleton for back-end developers I work with. This helps to find mistakes in the UI/IA and costly re-writes before the site is implemented.
I would like to take this a step further and create these prototypes/skeletons in Django. By a prototype/skeleton I mean linked static pages that can be easily hooked up to back-end later.
I would like to get some suggestions/ideas how I should set up my templates/links so they are easy to work with later during the implementation stage.
Short list of requirements that come to my mind:
Organization of templates while the entire project will consist of multiple apps
Clean URL dispatcher and link creation
Ability to display logged-in/ logged-out states
I guess in a more traditional approach, the UI designers and back-end developers work on two ends of the development spectrum and hopefully converge somewhere in the middle in a gracious manner. If you'd be willing to get your hands dirty with writing a few lines of code, you could lay out the whole application architecture for the developers because you have the upper hand—your immediately concerned with the users, the data they consume and the interactions they need to perform. That would take out much of the guesswork for the developers, now with only having to fill in the holes, connect the dots or what have you.
The first thing you should do is get together and set some common grounds. Typically, that includes performing modularization at the very beginning. Take all the major features and break them into several Django apps that are going to wrap template, view and model triads relevant to a certain feature the application provides. The more the better holds true here, so don't worry if you end up with a lot of applications, because you never want to have a single application providing too many features/hosting too many components. Commonly you start with apps such as registration, authentication, profiles (user) and work you way outwards. As an example, you could cram the three into a single application, but you end up with a lot of templates, a lot of views, two or three models perhaps, but the tests are really going to be a real choking point. So, break everything into these app buckets until you feel that every part of the system naturally falls into place on a conceptual level. If your ever find yourself thinking where something should be placed, or your looking at a module that's several pages long and feel tempted to break the module (models.py, views.py, test.py) into a package with many intra-package modules, you should probably refactor the architecture immediately. Always remember that your efforts here are to strike simplicity with your architecture.
Once that's done, you've really done half of the work. Great thing about Django is that you have loose coupling between URLs and views. The views themselves provide the application behavior and streamline the presentation. If you can properly pave out the main URLs and stub out the views to just churn out static templates, you've just done some fine work.
This is how it's accomplished. You can abstract URLs and the views they're mapped to by naming your patterns, such as authentication:login, authentication:logout, registration:register, registration:confirm, registration:activate, etc. This is how you tie your internals to all the behaviors that are provided and these shouldn't be subject to change. You can then always change the URL pattern for authentication:login, change the view that pattern maps to, but your referencing it by an internal name, so you can, say, swap out the views that just churned out static templates with a full blown view without having to do any additional modifications to your code.
So here's how it works in real life:
Brainstorm, decide on the apps and the features they'll provide and review your decisions.
Start of with a core application that's going to host some project specific features, such as base templates and the root / view.
Create a /core/templates/core/base.html that's going to load all the common CSS/JS files that are going to be used site-wide, that'll define the header, contents and footer sections (template blocks) and that's going to use context variables for page metadata, such as title, description, keywords and robots. Your typical "One Template To Rule Them All", the bits that are going to be present in structure/presentation for all of your pages.
Create a simple /core/temaplates/core/welcome.html, that extends the core template and prints "Hello world!" in the content area.
Add the following to /core/urls.py:
from django.conf.urls.defaults import *
from django.views.generic import TemplateView
urlpatterns = patterns('',
# Welcome
url(
r'^$', TemplateView.as_view(template_name='core/welcome.html'),
name='welcome'
),
)
Hook it up in the main /urls.py:
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(ur'^', include('core.urls', namespace='core')),
url(ur'^admin/doc/', include('django.contrib.admindocs.urls')),
url(ur'^admin/', include(admin.site.urls)),
)
Hit http://localhost:8080/, see the "Hello World!", revel in the warm fuzzy feeling.
Repeat the same for the rest of the apps: create the app, create the patterns, name them, map them to a static template, hook it to a namespace in the main urlconf.
You can push the views even further to production readiness for the developers. It might depend on the devs and their style guidelines, but I like to keep my /urls.py clean of everything else but patterns, names and view mappings. Your /core/urls.py could look like:
from django.conf.urls.defaults import *
from core import views
urlpatterns = patterns('',
# Welcome
url(
r'^$', views.Welcome.as_view(),
name='welcome'
),
)
Edit /core/views.py with the following:
from django.core.views.generic import TemplateView
class WelcomeView(TemplateView):
template_name='core/welcome.html'
extra_context={
'page_title': 'Welcome!',
'page_keywords': 'relevant,page,keywords',
'page_description': 'Something equally relevant',
}
def get_context_data(self, **kwargs):
context = super(WelcomeView, self).get_context_data(**kwargs)
context.update(self.extra_context)
return context
And that's one sturdy stubbed-out view, packed with page metadata! Definitely the stuff that'll earn you a beer from the devs. Keep on doing this for all of the views to pump out static templates. When someone approaches to finalizing the views, they'd just have to inherit from a different view class, add the missing features, extend the context, modify the template and voila--it's ready for production.
There's not a lot of upfront learning you'd have to do to make this possible, but it really takes out a lot of the guesswork for devs, which are naturally more concerned with building the rest of the application. It's also simple enough to get really good at, I would guess no one would mind letting you do all of this work. As added beef, you'll probably not be kept in the dark as to how the template context gets populated in the views, so even you can start rolling out more complex views, or at least be able to read them.
When I start an application, I usually make a prototype version as well in Django. I just use direct_to_template generic views, which can later be replaced with the views that the developers create. Since you have multiple apps, you can store app specific templates in a folder in your templates folder that has the same name as the app.
The end result is that you have all the screens displaying at the right urls and can link between them. All developers need to do is replace each url with the custom view they create. Makes it easy.
You may have to do a bit of code if you want the logged in/out status to display, but it is definitely doable.