(GCBV) How to call custom method to publish blog (UpdateView) - django

Good day SO!
Next to Java I'm trying to learn some Python/Django since the company I work for is also going to use Django. However, I am trying to figure out how to work with Generic Class Based Views. I hope somebody can give me some information to guide me in the right direction to solve my problem.
I have a small blog application containing CRUD (Create, Read, Update, Delete) abilities with GCBV (Generic Class Based Views). In the Detail view I have a link to publish:
{% url 'blogs:publish' blog.pk %}
which i want to use like:
url(r'^(?P[0-9]+)/publish/$', xxx, name='publish')
I just can't get it to work. I have attempted (and simular attempts) to create a method in the Update(UpdateView) class called publish(self, **kwargs): and make the url pattern to call it:
url(r'^(?P[0-9]+)/publish/$', views.Update.publish(), name='publish')
which obviously doesn't work, otherwise you wouldn't be reading this right now ;) I've been reading quite some docs/google/etc, but mostly it's function based or the tutorial stops after CRUD. Can you push me in the right direction (tip/clear tutorial/example) or an explanation where I'm taking the wrong choices? Thanks in advance!

UpdateView is used for updating, but you may take a look at CreateView. It is used to create objects.
Also you need to understand that you can't call a method as it's even hard to imagine how it has to work. GCBV are just sequences of already written methods which make your life easier. You can overwrite GCBV basic methods and create your own, which then can be used inside the view, but you can't call them in the urls.

Related

Need help regarding design of Django urls and views

Apologies if this has been discussed before, have searched and searched but didn't find anything useful :)
But here goes.
We're currently in the process of rewriting a portion of our webapp. Our app is rather old and therefore suffers from some rather cowboy'ish approaches to programming, conventions and urls.
What we're looking for is a simple clean way to design our views and urls so that we can maintain both easier in the future.
The problem is; as of now our urls.py file for the main site is one big mess. a lot of urls that point to a unique view that only does one thin.
Ex. list_books/, edit_book/ etc.
when it comes to specific formats etc. we have something like list_books_json/
(these aren't the actual urls though, but just used to prove a point since the real urls are much worse)
What we want to do now is clean it up a bit. And we we're wondering what the best way to get around it would be??
What we have thought of so far(after reading a lot of things on the subject):
We've thought of designing our urls after the following pattern:
domain/object/action/
so the urls for the apps "staff" site for changing books in the app would be:
staff/books - to view all books (GET)
staff/books/ID - to view one books (GET)
staff/books/new - to create a new book (POST)
staff/books/ID/edit - to edit specific books (POST)
staff/books/ID/delete - to delete specific books (POST)
The thought was then to have only 1 view, views.staff_books() to handle all these actions when dealing with books through the "staff" part of the site.
so that staff_books() checks for ID or a certain "action" (edit, new, delete etc.)
The result would be fewer, but a lot larger views that have to handle all aspects of staff/books. Right now we have a ton of small views that handle only one thing.
Does this makes sense, can you see potential problems? How do you guys go about it??
One place where I think we're lost is in regards to formats.
Where would you put ex. the request for returning the response in json?
we're wondering "staff/books.json" or "staff/books/ID.json" etc. and then keeping all the json logic in the same "staff_books()" view.
So thats it basically. I'm sorry the question is a little "fluffy"... We basically need some examples or good design advice as to how to structure urls and views.
Kind Regards
pete
As an extension (and solution) to your problem I would suggest to use the strategy pattern. Since you already have a structure and the only thing that differs is "how" it is supposed to be carried out, this pattern fits your problem perfectly. What I mean by that is the following:
Create a view which is your entry point to your application with functions named as your url-based functionality (edit, new, delete etc.). I.e where your url.py determines where to go from there.
Create classes which do your stuff based on your domains etc. Lets call them Book, Calendar etc for now.
Implement functionality of those classes, like edit, new, delete etc.
in your view then, determine what class to instantiate and call the corresponding function, e.g in View.edit() call domain.edit()
I think that should do it ^^
Hope it helps :D

local fields list not overriding correctly in Django-piston

Has anyone experience issues with this but in Django-piston that doesn't allow you to override fields already set?
https://bitbucket.org/jespern/django-piston/issue/192/object-handler-fields-override-local-field
Can anyone help me with a work around? I saw there is an easy patch but I don't want to go in and change the code in piston. Is there a way around it?
I'm using django-piston for quite a long time. There are a couple of issues with when you specify model = Foo. I simply use it to organize web service's urls, OAuth and Django Authentication. I still dont have any issue with it (yet). If you dont have any special reason to use model = Foo and fields I think you can call the model within read and create.
Hope it help :)
If you dont want to apply the patch yourself, and you dont want to avoid using certain model references on handlers to work around the issue, then maybe just clone the fork of piston that contains the patch being pushed to the main repo:
https://bitbucket.org/rptirrell/django-piston/overview
Its up to date aside from that and its trivial to swap it out to the main repo whenever you want.

Application logic in view code

Should I be writing application logic in my view code? For example, on submission of a form element, I need to create a user and send him an activation email. Is this something to do from a view function, or should I create a separate function to make it easier to test down the road? What does Django recommend here?
I found it very hard to figure out where everything goes when I started using django. It really depends on the type of logic you are writing.
First start with the models: model-methods and managers are a good place to perform row-level logic and table level logic i.e. a model manager would be a good place to write code to get a list of categories that are associated with all blogposts. A model method is a good place to count the characters in a particular blogpost.
View level logic should deal with bringing it all together - taking the request, performing the necessary steps to get to the result you need (maybe using the model managers) and then getting it ready for the template.
If there is code that doesn't fit in else where, but has a logical structure you can simply write a module to perform that. Similarly if there are scraps of code that you don't think belong, keep a utils.py to hold them.
You shouldn't perform any logic really in your templates - instead use template tags if you have to. These are good for using reusable pieces of code that you you neither want in every request cycle nor one single request cycle - you might want them in a subset (i.e. displaying a list of categories while in the blog section of your website)
If you do want some logic to be performed in every request cycle, use either context processors or middleware. If you want some logic to be performed only in one single request cycle, the view is probably the place.
TLDR: Writing logic in your view is fine, but there are plenty of places that might be more appropriate
Separating the registration code into it's own function to make testing easier is a good reason. If you allowed admins to register users in a separate, private view, then a registration function would be more DRY. Personally, I don't think a little application logic in the code will do to much harm.
You might find it instructive to have a look at the registration view in the django-registration app -- just to see how it's written, I'm not saying you should or have to use it. It has encapsulated the user registration into it's own function (there's a level of indirection as well, because the registration backends are pluggable).

Sharing view logic in Django

I've begun diving into Django again and I'm having trouble finding the parallel to some common concepts from my life in C#. While using .NET MVC I very often find myself creating a base controller which will provide a base action implementation to take care of the type of stuff I want to do on every request, like retrieving user information, getting localization values.
Where I'm finding myself confused is how to do this in Django. I am getting more familiar with the MVT concept but I can't seem to find how to solve this scenario. I've looked at class based views and the generic views yet they didn't seem to work how I expected. What am I missing? How can i create default logic that each view will be instructed to run but not have to write it in each view method?
If it is truly common for your whole site you use middleware. If it is only common for some views, the way to go in my opinion is to create decorators for those views. I never use class-based views because I tend to keep views simple and put more logic into models, so I have no need for classes there.

implementing a template tag within a generic app - django

I have developed some code that builds on the contrib comments app, such as handlers for ajax requests. This code is in a separate application, which we can call 'comments2'. the url configuration of the project is structured in such a way that all calls to /comments are directed to this app's views. This works without problems.
Very recently I made a new page that shows comments flagged as inappropriate.
I conceived that it was best done by writing an inclusion templatetag, and wrote one. It works like this:
{% display_flagged_comments 'market' %}
This tag is placed inside the main app's relevant template.
As seen in the code above, I pass what model (Market in this case) the comments belongs to so that the comments2 app remains generic.
I have three issues here that I need guidance on:
First, I feel that the model argument being inside quotes ('market') make the code somewhat less elegant. In the code the argument is converted to a model:
#template tag
def show_comments(modelname):
model = ContentType.objects.get(model=modelname)
... # get comments and return them
Second, since all requests with /comments are directed to comment2 app, I need to devise a different url for this page (it sits inside the main app), such as /managecomments. I find doing that also inelegant.
Third, I want to know if I followed a correct path or is there a better way to implement what I'm trying to do.
Thanks in advance.
The ContentTypeManager has somewhat solved your first problem for you. You can use the method get_for_model, which accepts both a class or an instance. Read more at the contettypes docs.