How about having a SingletonModel in Django? - python

I'm making a very simple website in Django. On one of the pages there is a vertical ticker box. I need to give the client a way to edit the contents of the ticker box as an HTMLField.
The first way that came to mind was to make a model Ticker which will have only one instance. Then I thought, instead of making sure manually that only one instance exists, perhaps there is (or there should be) something like a SingletonModel class in Django, which is like a normal model, except it makes sure no more than one instance gets created?
Or perhaps I should be solving my problem in a different way?

Try django-solo, it works in django 1.5 + for sure, django-singletons doesn't work with 1.5 + because it uses a deprecated feature.

You can use django_singletons. It has a built in admin support.

I think having a "singleton" model is ugly; it's dumb use of the relational database and it's bad UI, because the admin UI is built around working with lists of objects.
Instead I prefer to use a generic solution like django-chunks or django-flatblocks for this.

rewrite your save method so that every time a Ticker object gets saved it overwrites the existing one (if one exists).

A model with only one instance, a singleton, is sometime useful for things like global settings that you want to edit from the admin instead of having them in Django settings.py.
There are several third party applications that helps implementing singleton models and improve the admin interface for instance, django-solo, django-singleton-admin, django-singletons.

Related

Django MVT design: Should I have all the code in models or views?

I'm pretty novice so I'll try to explain in a way that you can understand what I mean.
I'm coding a simple application in Django to track cash operations, track amounts, etc.
So I have an Account Model (with an amount field to track how many money is inside) and an Operation Model(with an amount field as well).
I've created a model helper called Account.add_operation(amount). Here is my question:
Should I include inside the code to create the new Operation inside Account.add_operation(amount) or should I do it in the Views?
And, should I call the save() method in the models (for example at the end of Account.add_operation() or must it be called in the views?)
What's the best approach, to have code inside the models or inside the views?
Thanks for your attention and your patience.
maybe you could use the rule "skinny controllers, fat models" to decide. Well in django it would be "skinny views".
To save related objects, in your case Operation I'd do it in the save() method or use the pre_save signal
Hope this helps
Experienced Django users seem to always err on the side of putting code in models. In part, that's because it's a lot easier to unit test models - they're usually pretty self-contained, whereas views touch both models and templates.
Beyond that, I would just ask yourself if the code pertains to the model itself or whether it's specific to the way it's being accessed and presented in a given view. I don't entirely understand your example (I think you're going to have to post some code if you want more specific help), but everything you mention sounds to me like it belongs in the model. That is, creating a new Operation sounds like it's an inherent part of what it means to do something called add_operation()!

Django: Get notified of all changes in database

I was wandering if there's a way to get notified of any changes to objects in a Django database. Right now I just need an email if anybody adds or changes anything but it would be best if I could hook a function triggered by any change and could decide what to do.
Is there an easy way to do it in Django?
Two ideas come to mind:
Override the predefined model method for saving.
Use a signal like post_save.
Here is a good article that talks about the difference between the two things listed above and when to use them:
Django signals vs. custom save()-method
The article was written near the end of 2007, three days after the release of Django 0.96.1. However, I believe the advice the author gives still applies today.

Is Django's update_object generic view secure? Should I extend it or make my own for security?

I'm new to Django. Last night I worked hard on a view that would allow me to edit any of the entities in my current project; Chapters, Stories, and Worlds. In order to ensure that I know precisely which database object is being modified, I added a database entry to the tables 'edits' that stores the hash, the type of object being edited (eg. 'Chapter'), and the id of that object as found in the database. The hash is added to the form as a hidden input.
On the back-end, after the form has been submitted, I grab the hash and use it to find the related Edit item in the database. I then use this to find which object was initially being edited. This was done for two reasons:
I can know what object is truly being edited. If all form items have changed, there would be nothing to compare to (except URLs) to actually know which object is being edited.
Users should be unable to hack the front-end to do weird things like modify the wrong stories.
Today I discovered that Django has a generic view called update_object. This seems to handle a lot of things for me. But given that it doesn't automatically use the database to ensure that the correct object is being edited, or even determine which object is being edited, is this secure? surely there must be a simple way to hack it on the front end by modifying HTML elements.
Secondly, if this should be a concern, would you recommend that I keep my own edit view, or that I extend the update_object view, or some other solution?
Lastly, am I going about this the right way at all? Please correct me if I'm not thinking about solutions to this problem in the right way.
I don't feel that this is a question that requires code. It's more of a general question about the security of forms as they pertain to Django.
Thanks,
ParagonRG
Your problem of knowing which object they're editing is typically solved either by inspecting the URL or by a hidden form element that just has the database ID.
Before accepting any changes from a user form, you should be verifying that the user has permission to do whatever it is they're asking to be doing, and that the edits make sense. You'd normally do this with form validators and/or explicit checks in the view. This is a somewhat safer way of dealing with this problem, because it guarantees people aren't making DB changes they're not allowed to be making, whereas in your Edit object approach it's conceivable they could get around that.
If you take this approach, I don't see any reason why it's a problem that the user could be editing hidden ID fields to pretend to be editing a different object. They're just using a silly roundabout way to edit things when they could have just gone to a different edit link.
(Also: if you're using Django 1.3+, it's better to use the new class-based UpdateView rather than the function-based update_object.)

Is it safe to access ._meta directly in your django app?

Django uses Meta class for lots of additional object information. However, they store this information in an object '_meta' which by naming convention is private.
All over the django admin (and other places) I see stuff like opts = model._meta and then they use the various options like app_label and verbose_name.
Can I be confident accessing ._meta and be sure that it will not change in the future, or am I better off creating one 'accessor' mixin or something that accesses the ._meta in one spot, so if it ever does change I only have to update one thing?
I use _meta frequently and haven't had any issues so far. You can see in the django documentation an example of them using it too here, so I have felt its more or less ok to do. Just tread carefully and write good tests so you know of any problems when you upgrade your django version later on down the road.
I use _meta in several projects where I want to have generic access to information that's otherwise not provided by the api. I think you're probably okay most of the time as Django is pretty stable. It's probably a good idea to be covering your usage of _meta in your unit tests.

Django and monkey patching issue

I have recently started experimenting with Django for some web applications in my spare time. While designing the data model for one, I came across the dilemma of using inheritance to define a user of the website or using a technique known as monkey patching with the User class already supplied by the framework.
I tried to add a field by means of (after having defined all my models etc. without errors, according to python manage.py validate):
User.add_to_class('location', models.CharField(max_length=250,blank=True))
and executed the syncdb command. However, I keep getting this error
OperationalError: no such column:
auth_user.location
whether I am in the admin view of the site or the manage.py shell. There must be an extra step I'm missing, but there seems to be limited documentation on the whole monkey patching technique. So I'm asking you for assistance before I resort to inheritance. Any code, tips, or pointers to additional documentation are of course welcome.
Thanks in advance.
PS. I'm aware this technique is ugly, and probably ill-advised. ;)
There's an alternative to both approaches, which is to simply use a related profile model. This also happens to be a well-documented, highly recommended approach. Perhaps the reason that the add_to_class approach is not well-documented, as you noted, is because it's explicitly discouraged (for good reason).
When you add a field to any model, even if you do it the 'official' way, you need to migrate the database - Django doesn't do it for you. Drop the table and run ./manage.py syncdb again.
You might want to investigate one of the migrations frameworks, such as south, which will manage this sort of thing for you.
Here's a (slightly older) way of extending the User model.
Here's what the docs have to say.
And here's a recent conversation on django-users about the topic.
Djangos framework uses metaclasses to initialize the tables. That means you can't monkey-patch in new columns, unless you also re-initialize the class, which I'm not sure is even possible. (It may be).
See Difference between returning modified class and using type() for some more info.
I guess you might run into problems regarding where is your monkeypatch defined. I guess django syncdb creates databse tables only from the "pure" auth application, so your model will then be without "location", and then your site with the patch will look for the field.
Probably less painful way of adding additional info to user profiles is described in Django docs.

Categories

Resources