This class runs a django test server in another thread. This is very useful for e.g. selenium integration. Simple to integrate into django test framework.
Usage:
server = TestServerThread("127.0.0.1", "8081")
server.start()
# Run tests e.g.
req = urllib.urlopen("http://127.0.0.1:8081")
contents = req.read()
server.stop()
ps. I don't actually double space my code :). Not sure whats up with that!
I'm using Django's FlatPages, but I want to be able to restrict admin access to Users based on a FlatPage url. For example, User John Doe should be able to edit any FlatPage objects whose URL begins with `/johndoe/` (such as `/johndoe/about/` or `/johndoe/projects/whatever/`).
For this to work, John Doe would already need the appropriate admin permissions for FlatPage (such as can_add and can_change).
I have set this up as a separate *flatpage_addons* app. It consists of the **Permission** model, which maps a starting URL to one or more django Users. It consists of the minimal necessary admin code so Permissions can be created using the admin.
The bulk of this code consists of the *ifhasflatpagepermission* template tag as well as the *flatpage_result_list* inclusion tag. The former works much like django's existing *if*, *else*, *endif* tags while the latter is modified from the django admin's *result_list* inclusion tag.
This may not be the most elegant solution to my problem, but so far it works for me. Any comments or suggestions are welcome!
Inserts the output of a view, using fully qualified view name (and then some
args), a or local Django URL.
{% view view_or_url arg[ arg2] k=v [k2=v2...] %}
This might be helpful if you are trying to do 'on-server' AJAX of page
panels. Most browsers can call back to the server to get panels of content
asynchonously, whilst others (such as mobiles that don't support AJAX very
well) can have a template that embeds the output of the URL synchronously
into the main page. Yay! Go the mobile web!
Follow standard templatetag instructions for installing.
**IMPORTANT**: the calling template must receive a context variable called
'request' containing the original HttpRequest. This means you should be OK
with permissions and other session state.
**ALSO NOTE**: that middleware is not invoked on this 'inner' view.
Example usage...
Using a view name (or something that evaluates to a view name):
{% view "mymodule.views.inner" "value" %}
{% view "mymodule.views.inner" keyword="value" %}
{% view "mymodule.views.inner" arg_expr %}
{% view "mymodule.views.inner" keyword=arg_expr %}
{% view view_expr "value" %}
{% view view_expr keyword="value" %}
{% view view_expr arg_expr %}
{% view view_expr keyword=arg_expr %}
Using a URL (or something that evaluates to a URL):
{% view "/inner" %}
{% view url_expr %}
(Note that every argument will be evaluated against context except for the
names of any keyword arguments. If you're warped enough to need evaluated
keyword names, then you're probably smart enough to add this yourself!)
This example shows, how to use database views with django models. NewestArticle models contains 100 newest Articles. Remember, that NewestArticle model is read-only. Tested with mysql.
Flatpages are great for simple html content. However, I wanted some way to associate a navigation menu (just a snippet of HTML) with one or more FlatPage objects. Additionally, I wanted to be able to edit these throught the Admin. This was my solution.
I work with multiple projects, many of which have multiple custom management commands defined. It can be hard to remember them, and slow to pick them out of the "manage.py help" list.
This quickie command lists all of a project's custom commands (along with their help text). Writing it was easy after looking at the source of django.core.management.
Open questions include: how do you decide which app to put this command in? Should this command list itself?
I've devised a DRY method of declaring django fieldsets:
** Example usage: **
1. Include the attached code in `fieldsets.py`
2. `models.py`:
from django.db import models
from fieldsets import Fieldset, ModelWithFieldsets
class Person(ModelWithFieldsets): #instead of models.Model
# this field will be placed in nameless fieldset
example_field = models.IntegerField()
# this fieldset will be grouped into one row
Fieldset(grouped=True)
first_name = models.CharField(max_length=64)
surname = models.CharField(max_length=64)
Fieldset("Contact Details", classes=('collapse',))
mobile_phone = models.CharField(max_length=10)
email_address = models.EmailField()
Fieldset("Address")
street_address = models.CharField(max_length=255)
# the next two fields will be grouped into one row of this fieldset
Fieldset.new_group(2)
suburb = models.CharField(max_length=64)
state = models.CharField(max_length=64)
3. `admin.py`:
from django.contrib import admin
from models import Person
from fieldsets import Fieldset
class PersonAdmin(admin.ModelAdmin):
fieldsets = Fieldset.get_fieldsets(Person)
admin.site.register(Person, PersonAdmin)
This example produces the equivalent of manually typing:
fieldsets = (
(None, {'fields': ('example_field')}),
(None, {'fields': (('first_name', 'surname'),)}),
('Contact Details', {
'fields': ('mobile_phone', 'email_address'),
'classes': ('collapse',)}),
('Address', {'fields': ('street_address', ('suburb', 'state'))})
)
But now if you want to rearrange your fields, rename, delete, insert, etc, you won't need to remember to update the fieldsets in the ModelAdmin.
This implementation is a bit of a hack, but I believe a cleaner equivalent should be implemented in django itself.
**General notes:**
- Set MEDIA_URL (or whatever you use for uploaded content to point to S3 (ie. MEDIA_URL = "http://s3.amazonaws.com/MyBucket/"))
- Put django-storage in project_root/libraries, or change the paths to make you happy.
- This uses the functionality of django-storage, but *not* as DEFAULT_FILE_STORAGE.
The functionality works like so:
**Getting stuff to S3**
- On file upload of a noted model, a copy of the uploaded file is saved to S3.
- On any thumbnail generation, a copy is also saved to S3.
**On a page load:**
1. We check to see if the thumbnail exists locally. If so, we assume it's been sent to S3 and move on.
2. If it's missing, we check to see if S3 has a copy. If so, we download it and move on.
3. If the thumb is missing, we check to see if the source image exists. If so, we make a new thumb (which uploads itself to S3), and move on.
4. If the source is also missing, we see if it's on S3, and if so, get it, thumb it, and push the thumb back up, and move on.
5. If all of that fails, somebody deleted the image, or things have gone fubar'd.
**Advantages:**
- Thumbs are checked locally, so everything after the initial creation is very fast.
- You can clear out local files to save disk space on the server (one assumes you needed S3 for a reason), and trust that only the thumbs should ever be downloaded.
- If you want to be really clever, you can delete the original source files, and zero-byte the thumbs. This means very little space cost, and everything still works.
- If you're not actually low on disk space, Sorl Thumbnail keeps working just like it did, except your content is served by S3.
**Problems:**
- My python-fu is not as strong as those who wrote Sorl Thumbnail. I did tweak their code. Something may be wonky. YMMV.
- The relative_source property is a hack, and if the first 7 characters of the filename are repeated somewhere, step 4 above will fail.
- Upload is slow, and the first thumbnailing is slow, because we wait for the transfers to S3 to complete. This isn't django-storage, so things do genuinely take longer.
This code is referenced in a [screencast](http://blog.vlku.com/index.php/2009/06/10/djangoeclipse-with-code-complete-screencast/) focused on showing a user how to configure Eclipse with PyDev to give you code complete, and breakpoints inside the IDE.
It comes from a [2007 blog post](http://bear330.wordpress.com/2007/10/30/how-to-debug-django- web-application-with-autoreload/) (I've replicated it in case that post ever disappears.)
If you have a model that has an "ordering" column, and you want to be able to re-position records (eg, order items by priority), this base class should make it fairly easy. To use it, you extend your model using this abstract class, then hook up the pre_save event to the pre_save event of the base class, and you're good to go. Whenever you save an item, it ensures that it has a valid "order" number. The meat of this class is the "move()" method. Just call instance.move(number) where instance is your model instance, and this class will do all the logic necessary to shift around the order numbers for you.
The code shown allows you, in GeoDjango, to reduce the number of points in your polygons. It helps reduce storage needs and makes queries run faster, at the cost of some precision. It provides a variation on the simplify() method that comes with the GEOS API, allowing you to specify a number of points instead of a distance tolerance.
It is set up as a management command so that you can run it with python manage.py. See the django docs for how to set that up.
The example shown assumes a table called CountyBorders with fields "name" and "mpoly." It should be straightforward to adapt it for your needs. Look at the first three lines of the simplify() method in particular for customization. The rest of the code is pretty generic, and it should run fast enough in a one-time batch process for most needs.
The algorithm tries to keep the 75 points that provide the most definition for the shape. Each point in a polygon defines a triangle with its immediate neighbors. If that triangle has no area (the degenerate case), it is a midpoint on the segment between its neighbors and adds no value whatsoever. This principle is extended to say that the larger the triangle, the more value the point has in defining the shape. (You can find more refined algorithms, but this code seems to work fine by visual inspection.)
Sometimes you need to filter foreignkey choices in admin interface, to objects created by user or meeting some other condition. In django 1.0 there is no formfield_for_foreignkey method in ModelAdmin class so we have to make a workaround. Here is the solution I have found to be the easiest for me.
If you have another application in the same Apache virtual host and also want to use the authentication from Django - this might help. It uses the Django cookie - so it will not work in another Apache virtual host.