Django project design question - django

I have just started to work on a django project( and learn django at the same time) and I came across some design questions that I can't really answer with my limited knowledge so I decided to ask it here. anyway Here is the questions:
1) where would you put raw queries. is it ok to put row queries in view.py files? My personal opinion is to put them only in models.py files.
2) where can you query db? can you call query methods in models.py, views.py, templates? I think they should be in models.py or views.py but not in templates. specifically calls like "MyModel__attribute_set__all" should not be used in templates.
Since I am new in django (and python) I am not really sure if I have the right idea about this. I appreciate for any feedback.

Sounds like you're on a good path already.
I try to:
Keep my views slim, in terms of code, and my models fat
keep my templates even slimmer and free of database lookups; if I have to do something that hits the DB that for some reason isn't viable to do in the view, I do it via a templatetag or filter so that it can improved and/or cached, and is also easy to find, and is as DRY as a can be
define and execute any raw SQL in the models that use it

where would you put raw queries. is it ok to put row queries in view.py files?
Queries are most commonly seen in the view.py; yes it's ok there.
My personal opinion is to put them only in models.py files.
If you're using the same query a lot then create a "manager" for the model. You'll put the very commonly used querys there. "Only" in there would be making life hard for yourself.
where can you query db?
Usually in views.py; not uncommonly in models.py.
can you call query methods in ... templates?
Technically it is possible but, logically, very strongly discouraged.
I think they should be in models.py or views.py but not in templates
I agree.

Related

Declarative mechanism for Django model rows

With some frequency, I end up with models who contents are approximately constant. For example, I might have a set of plans that users can sign up for, with various attributes -- ID, name, order in the list of plans, cost, whether the purchaser needs to be a student/FOSS project/etc.. I'm going to rarely add/remove/change rows, and when I do there's likely going to be code changes too (eg, to change landing pages), so I'd like the contents of the model (not just the schema) to be managed in the code rather than through the Django admin (and consequently use pull requests to manage them, make sure test deploys are in sync, etc.). I'd also like it to be in the database, though, so I can select them using any column of the model, filter for things like "show me any project owned by a paid account", etc..
What are good ways of handling this?
I think my ideal would be something like "have a list of model instances in my code, and either Django's ORM magically pretends they're actually in the database, or makemigrations makes data migrations for me", but I don't think that exists?
The two workable approaches that come to mind are to either write data migrations by hand or use regular classes (or dicts) and write whatever getters and filters I actually want by hand.
Data migrations give me all the Django ORM functionality I might want, but any time I change a row I need to write a migration by hand, and figuring out the actual state involves either looking in the Django admin or looking through all the data migrations to figure out their combined impact. (Oh, and if somebody accidentally deletes the objects in the database (most like on a test install...) or a migration is screwy recovering will be a mess.)
Just using non-ORM classes in the source is a clearer, more declarative approach, but I need to replacements for many things I might normally do in the ORM (.objects.get(...), __plan__is_student, .values(plan__is_student).annotate(...), etc.).
Which of these approaches is better presumably depends on how much ORM functionality I actually want and how often I expect to be changing things.
Are there other good approaches for this? Am I missing some Django feature (or add-on) that makes this easier?

Django--complex context or complex template?

I'm rather new to the Django world and am converting an existing Java/Javascript app to Django. The existing app has many complex queries and conditionals. I can solve most of those in the template, but it is starting to get ridiculous. Generally, is it better to put the database hits in the view and have a more complex context to pass to the template or simplify the context and burden the template? Or does it matter? Some quick figures--the database has 44 tables 16 of which are M2M join tables. There are four report templates--the only one I've tackled hits seven different tables. So far, I've found testing things in the template is quicker and more reliable than testing in the view class. But I'm inclined to push more of the logic back to the view and pass a more complex context to the template. Just wondering which way more experienced Django hands go....
Referencing the book Two Scoops of Django:
Fat Models, Thin Views, Helper functions, and stupid templates
try moving as much things into models as you can.

How can I automate urls for django generic views?

I have subclassed Django's generic views for my project. I use them extensively to create basic CRUD views on our front-end site. Some models have just a create view, some have a read and update, etc.
This works well but I still write a line of code for each URL. ie:
url(r'^referrer/create/$',ReferrerCreateView.as_view(), name='referrer_create'),
url(r'^referrer/$',ReferrerListView.as_view(), name='referrer_list'),
url(r'^referrer/(?P<pk>\d+)/update/$',ReferrerUpdateView.as_view(),
name='referrer_update'),
I then do this for every model and the views that model has. This doesn't seem to be a very DRY approach to me. Is there a good approach to automating these urls for any generic view that has been created for a model?
The solution is to create a method that will return a list of url() calls given a set of views. Something like
views = {
'base_name': 'referrer',
'create_view': ReferrerCreateView,
'list_view': ReferrerListView,
'update_view': ReferrerUpdateView,
}
def generate_urls(views):
return [
url(r'^%s/create/$' % views['base_name'], views['create_view'].as_view(), '%s_create' % views['base_name'],
# and so on
]
Then you just need to do
urlpatterns = patterns('', *generate_urls(views))
For every set of views you have.
That being said I believe you shouldn't do this. This solution (or any different implementations) is over complicated and will add an extra layer you'll need to go through if things go wrong.
There's nothing wrong of having some boilerplate code, especially configuration code, because it makes your life much easier to debug in the future.
I have the same very concern and I shared it here before
One answer was the use of django rest framework as it implements such url patterns on its own!?! I didn't experience this solution yet.
My workaround is to have a dedicated file for crud operations for every model.
By that solution I decreased the matching time , and grouped related model pattern in one file.
BUT I understand that wont fully solve your question

Django: One FormWizard for multiple models

Would it be possible/best practice to use 1 FormWizard for manipulating multiple models?
I've experimented with the FormWizard and have defined all the forms. The page 'flow' itself works like a charm. However with all the checks that need to be done and Models that are manipulated it feels like I'm sticking code in the form's __init__ and/or process_step() that really belongs in views.py. The docs even state: "Dont manipulate form data via process_step().
Testing a concept with everything in one view, thus using a last_submitted_page (the step equiv) it feels like I'm writing another formwizard.
Anybody been here before? Tips welcome.
Thanx a lot.
Regards,
Gerard.
Zooming out on the issue I decided to go for the FormWizard approach. I re-confirmed that code is easily placed in forms.py and that you can get your model info by using. the process_step().
GrtzG

Django and Generic Views

I've written an entire app pretty successfully in Django but I have this nagging question that I think I know the answer to but I just want to make sure.
One of the things I really liked about Django was the data model and the ability to not have to do "obvious" stuff. For example, we use the admin interface extensively in our app. The fact that I don't need to write an edit screen for every model and keep it up to date every time the model changes is really nice.
What I'm puzzled by is that I wanted to have one part of the app render "read-only" versions of the models. Essentially I want exactly what I have in the Admin interface but without editable widgets. Now I notice, from the Django code, that that admin interface actually goes through and substitutes the widgets to use the editable ones so I know that non-editable is certainly there.
But as far I can tell, there is no way to just say "render this object" and have Django do the "obvious" thing and render it just like it does for the admin interface but with non-editable fields. I find this hard to believe since it seems like a) this is easier than the admin stuff and b) I know the widgets are already there. But I've looked all over and even the Django examples seem to always create a template and spell out exactly what the page should look like.
Writing a template is probably a good idea in general but early on in development when things are changing it would be better to have something that just does something basic given the information available in the model.
Am I missing something? Sorry if this is a stupid question.
Could be that most non-toy sites want a custom layout/html anyway?
Or, are you looking for Databrowse?
I used something like this: http://www.djangosnippets.org/snippets/937/
There are other similar things around if you google for 'django read-only admin' or similar.
Never underestimate how flexible the Django Admin is...