django_tickets
id | created | changetime | last_pulled_from_trac | stage | status | component | type | severity | version | resolution | summary | description | owner | reporter | keywords | easy | has_patch | needs_better_patch | needs_tests | needs_docs | ui_ux |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 2005-07-13 19:03:27 | 2012-05-20 15:12:37 | 2022-03-06 03:19:23.152286 | Unreviewed | closed | Core (Other) | enhancement | normal | fixed | Create architecture for anonymous sessions | We need an architecture for anonymous sessions. Right now we have django.models.auth.sessions, but that only handles registered users' sessions. We need a system that automatically creates and manages sessions for anonymous users. Here's one idea for this: * In the settings file, you define a {{{SESSION_MODULE}}} string, like the {{{AUTH_PROFILE_MODULE}}}, which points to the model to use for sessions. * Using this, httpwrappers automatically creates a request.session object which is persistant across requests based on cookies, etc. | jacob | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
3 | 2005-07-13 19:06:09 | 2007-07-03 23:04:08 | 2022-03-06 03:19:23.472795 | Design decision needed | closed | Metasystem | enhancement | normal | fixed | Convert OneToOne to be like ForeignKey and ManyToManyField | Remove the boilerplate from {{{OneToOne}}}. | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
4 | 2005-07-13 19:08:10 | 2005-09-16 17:01:24 | 2022-03-06 03:19:23.630870 | Design decision needed | closed | Core (Cache system) | enhancement | normal | duplicate | Add a db cache backend | We should have a db cache backend -- this will be very useful for people who can't/won't run memcached. | jacob | adrian | 0 | 0 | 0 | 0 | ||||
5 | 2005-07-13 19:08:56 | 2007-02-25 17:31:18 | 2022-03-06 03:19:23.798789 | Design decision needed | closed | Metasystem | enhancement | normal | wontfix | Add a cache=NUM_SECONDS argument to QuerySet | It'd be convenient for the lookup API to have caching baked in. | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
18 | 2005-07-13 19:26:27 | 2007-07-03 23:03:51 | 2022-03-06 03:19:27.157564 | Unreviewed | closed | Database layer (models, ORM) | enhancement | normal | wontfix | Metasystem optimization: Don't select duplicate fields | In the following query, "poll_choices.poll_id" and "polls.id" are the same value. Only one of them needs to be selected: {{{ SELECT poll_choices.id,poll_choices.poll_id,poll_choices.choice, poll_choices.votes, polls.id,polls.slug,polls.question,polls.pub_date, polls.expire_date FROM poll_choices, polls WHERE poll_choices.poll_id = polls.id }}} | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
19 | 2005-07-13 19:31:17 | 2021-05-10 19:10:04 | 2022-03-06 03:19:27.337791 | Design decision needed | closed | Validators | enhancement | minor | new-admin | wontfix | Automatically generate JavaScript form validation | Django should generate JavaScript form validation for all admin pages, in addition to the server-side validation it already does. Each FormField object already gets an HTML class of the type of field it is (e.g. "vCheckboxField", "vEmailField", "vTextField"), so we can probably build off of that. OR, we could use {{{XMLHttpRequest}}} to send each field individually and validate everything *server-side*. ====================================================== I've given some more thought to this. We could set up a view that validates a given field via XMLHttpRequest, like this: admin.6newslawrence.com/validate_field/polls/polls/question/?value=blah (The "value=blah" would be POST data, not GET data.) But here's a problem: What do we do for validators that expect all_data, i.e. the ones that validate a field according to the value of another field? We could solve that by only using dynamic JavaScript? validation to check single fields and using server-side validation for the rest -- but it's a usability problem if some validation errors appear instantly and others appear after form submission. | adrian | adrian | validators | 0 | 0 | 0 | 0 | 0 | 0 |
20 | 2005-07-13 19:32:17 | 2007-07-03 23:03:44 | 2022-03-06 03:19:28.799681 | Ready for checkin | closed | contrib.admin | enhancement | normal | duplicate | "Add another" for many-to-many relationships | Django already creates an "Add another..." link in one-to-many select boxes. (Example: The "place" select box on the "Add event" admin page has an "Add another..." link at the bottom of it.) Many-to-many fields -- represented in the admin as multi-select boxes -- also need "Add another..." capability. It could probably appear as the last entry in the select box, as in the one-to-many add-anothers. | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
21 | 2005-07-13 19:33:01 | 2007-05-30 21:29:52 | 2022-03-06 03:19:29.033864 | Design decision needed | closed | contrib.admin | enhancement | trivial | fixed | FileUploadField should allow for manual filename entry | FileUploadFields currently don't allow users to type in the name of an ''already-existing file'' -- the system forces them to upload a new file each time. There should be a way of designating a path/filename on the server. It'd be great if there was some sort of filesystem-browsing interface, like the one Urchin has for selecting log sources. | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
28 | 2005-07-13 19:41:08 | 2007-07-17 21:49:58 | 2022-03-06 03:19:31.290643 | Accepted | closed | Metasystem | enhancement | normal | duplicate | Delete confirmation should have "replace relationships" shortcut | This is best explained with an example. Right now, when I click to delete a duplicate dateline, I get a list of all the news stories that feature that dateline. So I click on each story to change its dateline to the correct (non-duplicate) dateline, because if I didn't do that, deleting the dateline would delete all those stories. Then, once I've changed all the stories, I can delete the dateline safely, because it won't have any relationships. What I want is the delete-confirmation page for datelines -- and everything else -- to offer a "convert all of these stories' datelines to the following *different* dateline" select box. | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
38 | 2005-07-16 18:15:54 | 2007-07-03 23:03:57 | 2022-03-06 03:19:32.801848 | Unreviewed | closed | Database layer (models, ORM) | enhancement | normal | fixed | Create sqlite backend | An sqlite backend option would be useful for rapid-start development (ie. shortening the "unpack and try it" path. For an extreme case, look at roundup, and how you can download it, run one script from the source dir, and point a browser at it... django probably can't go *quite* that minimal, but with so many frameworks, having a quick way to "kick the tires" is very handy.) | jacob | eichin@thok.org | 0 | 0 | 0 | 0 | 0 | 0 | ||
41 | 2005-07-17 03:46:55 | 2007-07-03 23:03:22 | 2022-03-06 03:19:33.293160 | Unreviewed | closed | Core (Other) | enhancement | normal | wontfix | allow for multiple user identities with access rights to the database | The current design assumes that only one user identity will be used for all database operations - from creating the database through inits and on to access from mod_python. This makes it very difficult to use ident auth (suitable for small, single host setups) and may be an issue even whent hat's not an issue. It's probably not too hard to remove this limitation. requires * a setup option to list other user ids to be allowed access * generate SQL GRANT statement(s) whenever a table is created (sequences too?!) And I think that's about it, at least for postgres. | adrian | maney@two14.net | 0 | 0 | 0 | 0 | 0 | 0 | ||
51 | 2005-07-17 23:39:39 | 2007-07-03 22:54:15 | 2022-03-06 03:19:34.866064 | Ready for checkin | closed | Metasystem | enhancement | normal | 1.0 | wontfix | Create add_* methods for objects with a many-to many-relationship | Objects with a many-to-one relationship have an add_object method for adding the type of object on the "many" end of the relationship to the list of values within the type of object on the "one" end of the relationship. Objects with a many-to-many relationship, however, are lacking these methods. For example: two objects, Set and Tag, have a many-to-many relationship. The Set object should have an add_tag method and the Tag method should have an add_set method. | adrian | jcernelli@gmail.com | 0 | 0 | 0 | 0 | 0 | 0 | |
61 | 2005-07-18 16:17:34 | 2007-01-17 22:12:17 | 2022-03-06 03:19:36.456283 | Unreviewed | closed | contrib.admin | enhancement | normal | dev | fixed | [patch] auth.User admin form shouldn't require people to edit hashes | People shouldn't have to enter MD5 hashes in the password field. World Online never used the user form to create users or edit passwords, but now there's a demand for a better form. We can solve it with JavaScript. | adrian | adrian | 0 | 1 | 0 | 0 | 0 | 0 | |
62 | 2005-07-18 16:34:40 | 2006-10-22 15:54:23 | 2022-03-06 03:19:36.628513 | Unreviewed | closed | Documentation | enhancement | normal | fixed | Change tutorial to use easy development server, not mod_python | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | |||
63 | 2005-07-18 16:36:21 | 2007-07-03 23:03:59 | 2022-03-06 03:19:36.810796 | Ready for checkin | closed | Core (Other) | enhancement | normal | fixed | Factor django.core.handlers into subclasses to remove duplicate code | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | |||
64 | 2005-07-18 16:37:56 | 2007-07-03 23:03:39 | 2022-03-06 03:19:36.990398 | Accepted | closed | Core (Cache system) | enhancement | normal | fixed | Add cache middleware | It should be possible to say "Cache every page on this site." We'd use middleware for this. | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
65 | 2005-07-18 16:53:09 | 2007-01-17 22:12:34 | 2022-03-06 03:19:37.141424 | Unreviewed | closed | contrib.admin | enhancement | normal | fixed | [i18n] Internationalization and localisation | Ability to translate at least Admin UI into another language (using gettext?) and format date / time / numbers according to locale. I am willing to do Dutch, Russian and maybe Hebrew translation :) | hugo | ksenia@ksenia.nl | 0 | 0 | 0 | 0 | 0 | 0 | ||
67 | 2005-07-18 17:28:38 | 2007-07-03 23:04:03 | 2022-03-06 03:19:37.481269 | Accepted | closed | Core (Other) | enhancement | normal | fixed | Make specifying 'human-readable' name optional. | I noticed that in the fields for the models in tutorial 1, three out of the four 'human-readable' names were identical to the 'machine-friendly' names. Following the DRY principle, I think that the specifying the 'human-readable' name should be optional, defaulting to the machine-friendly name. Here is a svn diff for a (trivial) implementation: {{{ Index: django/core/meta.py =================================================================== --- django/core/meta.py (revision 174) +++ django/core/meta.py (working copy) @@ -1564,13 +1564,13 @@ # database level. empty_strings_allowed = True - def __init__(self, name, verbose_name, primary_key=False, + def __init__(self, name, verbose_name=None, primary_key=False, maxlength=None, unique=False, blank=False, null=False, db_index=None, core=False, rel=None, default=NOT_PROVIDED, editable=True, prepopulate_from=None, unique_for_date=None, unique_for_month=None, unique_for_year=None, validator_list=None, choices=None, radio_admin=None, help_text=''): - self.name, self.verbose_name = name, verbose_name + self.name, self.verbose_name = name, verbose_name or name self.primary_key = primary_key self.maxlength, self.unique = maxlength, unique self.blank, self.null = blank, null }}} | adrian | mmarshall at myrealbox dot com | 0 | 0 | 0 | 0 | 0 | 0 | ||
69 | 2005-07-18 18:12:19 | 2007-07-03 23:03:53 | 2022-03-06 03:19:37.795012 | Unreviewed | closed | Database layer (models, ORM) | enhancement | normal | fixed | Enhancing the MySQL backend | I've implemented the dictfetch*() functions. May not be extremely fast, but at least the functionality is there. I'm not sure about the edge cases, though; we probably want the mysql and postgres backends to do the same thing when, for example, fetchmany() is called going over the result set bounds. Document this in the docstrings? | adrian | Manuzhai <mail@manuzhai.nl> | 0 | 0 | 0 | 0 | 0 | 0 | ||
73 | 2005-07-18 21:05:45 | 2007-07-03 23:03:38 | 2022-03-06 03:19:38.438789 | Accepted | closed | *.djangoproject.com | enhancement | normal | fixed | Sample templates in the repository? | I wonder if it would be possible to have the templates for this site also in the repository. This would be a useful starting point for beginning users, but maybe it's impossible due to copyright issues or some such. Also, the need for these things may disappear when the next tutorial appears - but still... | jacob | Manuzhai <mail@manuzhai.nl> | 0 | 0 | 0 | 0 | 0 | 0 | ||
77 | 2005-07-18 23:55:33 | 2007-07-03 23:03:24 | 2022-03-06 03:19:39.048107 | Ready for checkin | closed | Database layer (models, ORM) | enhancement | minor | wontfix | The PostgreSQL code should use schemas instead of prefixes for namespaces. | Rather than append App_ before every table in PostgreSQL, you should use Schemas http://www.postgresql.org/docs/8.0/static/ddl-schemas.html. That's what they're there for, and it makes the database much more readable. | adrian | RahmCoff@Radio1190.org | 0 | 0 | 0 | 0 | 0 | 0 | ||
78 | 2005-07-19 00:51:50 | 2006-10-15 20:17:46 | 2022-03-06 03:19:39.189327 | Unreviewed | closed | Tools | enhancement | normal | fixed | Add a test suite for core functionality | Congratulations on the (slightly earlier than expected) launch of Django. It looks very cool, and the site is nicely put together. Just what Python needs. On initial evaluation I was surprised to find almost no test code. There are a few tests in one package, but no comprehensive unit test suite. Automated testing seems particularly important for the fiddly bits of code like your database caching system. It's also really valuable to have unit tests in an open source project; you're much less likely to get broken code if you require the tests pass. Adding unit tests after the fact feels like a lot of work, but the earlier you get a good test framework in place the easier it will be. And the sooner it pays off. Thanks for listening to my suggestion! Nelson | adrian | nelson@monkey.org | 0 | 0 | 0 | 0 | 0 | 0 | ||
87 | 2005-07-19 16:39:52 | 2007-01-17 22:12:17 | 2022-03-06 03:19:41.019035 | Unreviewed | closed | Database layer (models, ORM) | enhancement | normal | duplicate | [patch] Oracle database support | Here's a patch for Oracle support. | adrian | jrhuggins@thoughtworks.com | oracle database db sequence | 1 | 0 | 0 | 0 | |||
90 | 2005-07-19 20:12:48 | 2007-07-03 23:03:41 | 2022-03-06 03:19:41.483591 | Unreviewed | closed | Tools | enhancement | normal | fixed | Add "django-admin.py inspectdb" option | {{{django-admin.py inspectdb}}} would take an argument -- the database name -- and would introspect the existing database-table structures and print a Django model to standard output. | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
91 | 2005-07-19 21:45:54 | 2007-07-03 23:05:24 | 2022-03-06 03:19:41.637006 | Accepted | closed | Core (Other) | enhancement | normal | duplicate | A (possible) cleaner ORM fields description | Here is a cleaner approach to the ORM fields. Using this patch, the example in the tutorial can be changed to this: {{{ from django.core.meta import Model # Create your models here. class Poll(Model): def fields(Field): Field.Char('question', maxlength=200) Field.DateTime('pub_date', 'date published') class Choice(Model): def fields(Field): Field.ForeignKey(Poll) Field.Char('choice', 'choice', maxlength=200, core=True) Field.Integer('votes', 'votes', core=True) }}} I have done an implementation, which is fully backwards compatible, and quite simple. {{{ Index: django/core/meta.py =================================================================== --- django/core/meta.py (revision 227) +++ django/core/meta.py (working copy) @@ -377,12 +377,53 @@ new_v.func_globals[k] = func new_functions[k] = func + +class FieldGenerator(object): + """FieldGenerator is used for... uh... Generating fields. It has attributes, + such as "Char" and "DateTime", that can be used to create class instances such as + "CharField" or "DateTimeField". These instances are then added to the list "fields", + which can be retrieved to be used as the "fields" attribute in a Model class.""" + def __init__(self): + self.fields = [] + self.last_class = None #This is the class obj that corrisponds to the last __getattr__ call. + + def __getattr__(self,name): + self.last_class = None + try: + obj = eval(name+"Field") + if issubclass(obj,Field): self.last_class = obj + except NameError: pass + if not self.last_class: # If name+"Field" didn't work, just try name. + try: + obj = eval(name) + if issubclass(obj,Field): self.last_class = obj + except NameError: pass + if not self.last_class: + raise AttributeError("Could not find either %s or %sField (or they are not decendants of Field.)" % (name,name)) + return self.GenerateField + + def GenerateField(self, *args, **kargs): + """ This creates an instance of the class corrisponding to the + last __getattr__ call, and adds it to self.fields.""" + if not self.last_class: + raise ValueError("GenerateField should only be called with self.last_class set.") + self.fields.append(self.last_class(*args, **kargs)) + self.last_class = None + + class ModelBase(type): "Metaclass for all models" def __new__(cls, name, bases, attrs): # If this isn't a subclass of Model, don't do anything special. if not bases: return type.__new__(cls, name, bases, attrs) + + # If 'fields' is callable, we want to call it, passing a FieldGenerator. + if callable(attrs['fields']): + fg = FieldGenerator() + attrs['fields'](fg) + attrs['fields'] = fg.fields # If this model is a subclass of another Model, create an Options # object by first copying the base class's _meta and then updating it }}} I don't know if this is the best way of doing it... but it's out there! | adrian | mmarshall | 0 | 0 | 0 | 0 | 0 | 0 | ||
98 | 2005-07-20 00:28:49 | 2007-07-03 23:04:10 | 2022-03-06 03:19:42.698394 | Ready for checkin | closed | Documentation | enhancement | normal | fixed | Pretty CSS for PHILOSOPHY sections in docs | Every now and then in the tutorials there's a section starting with PHILOSOPHY which outlines some of the thinking behind Django's design. It would be nice if these were set apart from the rest of the content a bit, by being in a box with a different background colour and a picture of a lightbulb or thinking greek guy or something. See here for an example: http://www.djangoproject.com/documentation/tutorial1/#creating-models | wilson | Simon Willison | 0 | 0 | 0 | 0 | 0 | 0 | ||
99 | 2005-07-20 00:48:15 | 2007-07-03 23:03:32 | 2022-03-06 03:19:43.264801 | Design decision needed | closed | Core (Other) | enhancement | normal | fixed | enhance model "ordering" to reduce redundancy for multiple same-order fields | currently: ordering = ( ('last_name','ASC'), ('first_name','ASC'), ('middle_name','ASC'), ('name_suffix','ASC'), ) suggested: ordering = ((('last_name','first_name','middle_name','name_suffix'),'ASC'),) Looks like the same "string or sequence of strings" trick, but going the other way this time! Should be backwards compatible, too. | adrian | maney@two14.net | 0 | 0 | 0 | 0 | 0 | 0 | ||
101 | 2005-07-20 01:28:53 | 2006-08-29 10:50:06 | 2022-03-06 03:19:45.011425 | Unreviewed | closed | Core (Management commands) | enhancement | normal | wontfix | Add functionality to django-admin to create skeleton views | You should be able to do something like {{{django-admin.py createview APPNAME VIEWNAME method1 method2 ...}}} and having {{{apps/APPNAME/views/VIEWNAME.py}}} created and filled with some sensible template (eg., comments on how to create methods, etc.) With a bit of work, it could be possible even modifying {{{apps/APPNAME/urls/APPNAME.py}}} to point to the new methods. See the attached patch. | adrian | ricardo@conysis.com | 0 | 0 | 0 | 0 | 0 | 0 | ||
105 | 2005-07-20 09:00:38 | 2007-01-17 22:12:17 | 2022-03-06 03:19:45.843137 | Unreviewed | closed | contrib.admin | enhancement | normal | fixed | Make collapse class to work in two ways | It is really useful to present some fieldsets collapsed in the admin interface and just with one click get them opened. It would be equally useful, once uncollapsed, to have the possibility to collapse them again. In a such way users can better organize the space on their Django admin interface. | jacob | paolo | 0 | 0 | 0 | 0 | 0 | 0 | ||
110 | 2005-07-20 14:23:10 | 2006-09-14 01:25:57 | 2022-03-06 03:19:46.627726 | Unreviewed | closed | Documentation | enhancement | normal | fixed | Documentation on pagination needed | Third path of tutorial should show views that don't return output and polls list with paging support. | jacob | maurycy | 0 | 0 | 0 | 0 | 0 | 0 | ||
115 | 2005-07-20 17:37:01 | 2007-10-21 19:53:27 | 2022-03-06 03:19:47.413935 | Accepted | closed | Core (Other) | enhancement | normal | invalid | Models CRUD via web services | Sometimes we need to offer public avaible CRUD API for existing models. That doesn't request too much creativity and can be generated automatically. It would be great to have them out of box, like admin interface. | nobody | maurycy | feature_request | 0 | 0 | 0 | 0 | 0 | 0 | |
117 | 2005-07-20 18:25:32 | 2007-07-03 23:04:07 | 2022-03-06 03:19:47.720239 | Unreviewed | closed | *.djangoproject.com | enhancement | normal | wontfix | Site search and/or Trac search for djangoproject.com | According to TracSearch, Trac has a neat feature where you can enter bug numbers, changeset codes etc in to the search box to jump directly to that item within Trac. It would be useful if the Trac search box was added to the templates for code.djangoproject.com in the same place on every page (it might work in the top right in the light green bar, below the Home / Download / etc links). Even better - how about adding search to the whole of the djangoproject.com website? It would be very handy for searching through the growing piles of documentation, not to mention the comments. | jacob | Simon Willison | 0 | 0 | 0 | 0 | 0 | 0 | ||
119 | 2005-07-20 19:42:19 | 2006-10-22 16:18:52 | 2022-03-06 03:19:48.032022 | Unreviewed | closed | Core (Other) | enhancement | normal | wontfix | Serving media | There is currently no way of serving media through Django, which might be alright for mod_python as it's counting on Apache, but the WSGI server doesn't have such benefits. | adrian | brantley (deadwisdom@gmail.com) | media wsgi images | 0 | 0 | 0 | 0 | 0 | 0 | |
121 | 2005-07-20 20:20:29 | 2007-07-03 23:04:25 | 2022-03-06 03:19:48.338497 | Accepted | closed | Metasystem | enhancement | normal | fixed | [patch] Names in SQL should be quoted | Some valid Python-identifiers are reserved words in SQL-databases, for instance "when" in PostgreSQL. It would be very nice, if Django would quote all names (e.g. schema, table, row) in SQL statements, so these database-reserved words would not pose problems. | adrian | sune.kirkeby@gmail.com | sql | 0 | 1 | 0 | 0 | 0 | 0 | |
122 | 2005-07-20 21:25:02 | 2007-01-17 22:12:17 | 2022-03-06 03:19:48.493110 | Unreviewed | closed | Core (Other) | enhancement | normal | fixed | [patch] Build models using fieldname=FieldClass | This is a patch to make fieldname=FieldClass type model definitions possible. It is fully backwards-compatible with the fields=(...) method. The example given in the tutorial could be re-written as such: {{{ from django.core import meta class Poll(meta.Model): question = meta.CharField(maxlength=200) pub_date = meta.DateTimeField('date published') class Choice(meta.Model): ForeignKey = Poll choice = meta.CharField(maxlength=200) votes = meta.IntegerField() }}} Other ways of defining a ForeignKey: {{{ #multiple keys can be used with tuples: ForeignKey = Poll, OtherKey #options can also be used: ForeignKey = Poll, {'edit_inline':True, 'num_in_admin':3} #the attribute name is irrelevant here: anything = ForeignKey(Poll, edit_inline=True, num_in_admin=3) }}} The implementation is quite simple. (or horribly hackish, depending on how you see things.) It simply goes through all of the attributes of the class, and adds all of the instances of 'Field' to the fields list. (after updating their names with the attribute name.) It also processes the ForeignKey field, producing ForeignKeys as needed. Provisions are in place to maintain the order of the Fields. Here is the patch: {{{ Index: django/core/meta.py =================================================================== --- django/core/meta.py (revision 253) +++ django/core/meta.py (working copy) @@ -368,6 +368,40 @@ if not bases: return type.__new__(cls, name, bases, attrs) + # We must refactor the attributes around a little. All Field class instances will be given + # names (as needed) and moved to the fields list. + + attrs["fields"] = attrs.has_key("fields") and list(attrs["fields"]) or [] + + def handle_ForeignKey(obj): + if isinstance(obj, Model): + attrs["fields"].append(ForeignKey(obj)) + elif type(obj) in (list, tuple): + if isinstance(obj[0], ModelBase) and type(obj[1]) == dict: + attrs["fields"].append(ForeignKey(obj[0], **obj[1])) + else: + for i in obj: handle_ForeignKey(i) + else: + raise ValueError("Cannot make ForeignKey from "+str(obj)) + + def handle_field(obj, name): + if isinstance(obj, Field): #Check if this is a field + if not isinstance(obj,ForeignKey): obj.set_name(name) + attrs["fields"].append(obj) + return True + elif name == "ForeignKey": + handle_ForeignKey(obj) + return True + return False + + # loop through the attributes, and take out the fields. + for key in attrs.keys()[:]: + if handle_field(attrs[key], key): + del attrs[key] # If the attr was added to fields, we want to delete it. + + # Sort the fields, so that they appear in the correct order. + attrs["fields"].sort(lambda x,y: x.creation_counter - y.creation_counter) + # If this model is a subclass of another Model, create an Options # object by first copying the base class's _meta and then updating it # with the overrides from this class. @@ -1551,14 +1585,19 @@ # database level. empty_strings_allowed = True - def __init__(self, name, verbose_name=None, primary_key=False, + # Will be increaced each time a Field object is instanced. Used to + # retain the order of fields. + creation_counter = 0 + + def __init__(self, name=None, verbose_name=None, primary_key=False, maxlength=None, unique=False, blank=False, null=False, db_index=None, core=False, rel=None, default=NOT_PROVIDED, editable=True, prepopulate_from=None, unique_for_date=None, unique_for_month=None, unique_for_year=None, validator_list=None, choices=None, radio_admin=None, help_text=''): self.name = name - self.verbose_name = verbose_name or name.replace('_', ' ') + self.original_verbose_name = verbose_name + self.verbose_name = verbose_name or name and name.replace('_', ' ') self.primary_key = primary_key self.maxlength, self.unique = maxlength, unique self.blank, self.null = blank, null @@ -1583,6 +1622,24 @@ else: self.db_index = db_index + # Increace the creation counter, and save our local copy. + self.creation_counter = Field.creation_counter + Field.creation_counter += 1 + + def set_name(self, name ): + """ + Sets the name, and generates the verbose_name from it if needed. + This function is here for when the name needs to be set later, + (such as if it needs to be obtained from the attribute name that + stores the Field instance.) + """ + if not self.original_verbose_name: + # If the verbose name was originally not specified, we will assume that + # the user intends for the first argument passed to __init__ to be the verbose_name. + self.verbose_name = self.name + + self.name = name + self.verbose_name = self.verbose_name or name and name.replace('_', ' ') + def pre_save(self, obj, value, add): """ Hook for altering the object obj based on the value of this field and }}} | adrian | anonymous | 0 | 1 | 0 | 0 | 0 | 0 | ||
130 | 2005-07-21 02:30:54 | 2007-07-03 23:04:15 | 2022-03-06 03:19:49.563314 | Ready for checkin | closed | *.djangoproject.com | enhancement | normal | wontfix | Display comments in Trac timeline | Jacob figured out how to do this on our internal Trac installation. Let's do it here, too. | jacob | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
136 | 2005-07-21 12:15:51 | 2007-07-03 23:04:35 | 2022-03-06 03:19:50.285213 | Design decision needed | closed | Documentation | enhancement | normal | fixed | Provide a path to read documentation files in docs/ (enhancement/trivial) | Yeah, it is really valuable to have a docs/ directory always rigorously up to date. The exposition is good also. However for people that approach Django for the first time it would be a great help to know if there is a *suggested* order to read documentation files. (Yes, I'm paranoid versus quality of documentation, it is too important!) It would be possible to specify that order in README file and add a prefix (00_, 01_, 02_ etc) in front of each file in docs/ This ticket is about a small but important!) change, anyway in my opinion it would be another great "welcome here" to newcomers :-) | jacob | paolo | 0 | 0 | 0 | 0 | 0 | 0 | ||
139 | 2005-07-21 17:21:05 | 2007-07-23 08:32:14 | 2022-03-06 03:19:50.687828 | Unreviewed | closed | contrib.admin | enhancement | normal | duplicate | edit_inline should grow some Javascript magic to increase usability | The edit_inline functionality is very nice, but I want more: * When I start typing in the last "Choices" field, I want a new, blank Choice entry to automagically appear below it. * When a new Choice entry appears, I want it properly inserted into the tab order so that I can just hit Tab and move to the new entry. In other words, it should be possible to create a new Poll, click on the first Choice tab, and start typing: Strongly agree <tab> 0 <tab> Agree <tab> 0 <tab> No opinion <tab> 0 <tab> Disagree <tab> 0 <tab> Strongly disagree <tab> 0 <enter> This would make adding an arbitrary number of choices much more streamlined. Currently I have to click the "Save and continue Editing" button after adding each choice, which means my hands have to leave the keyboard and travel over to the mouse. | tmervyn@gmail.com | rmunn@pobox.com | edit_inline | 0 | 0 | 0 | 0 | 0 | 0 | |
163 | 2005-07-22 17:58:19 | 2007-07-03 23:04:16 | 2022-03-06 03:19:55.009550 | Unreviewed | closed | Template system | enhancement | major | magic-removal | fixed | Option to leave off __exact | Doing {{{sites.get_object(id__exact = 1)}}} seems kind of verbose if {{{sites.get_object(id = 1)}}} would convey the same meaning and be a little easier to read. | adrian | Manuzhai | 0 | 0 | 0 | 0 | 0 | 0 | |
166 | 2005-07-22 20:10:11 | 2007-07-03 23:04:18 | 2022-03-06 03:19:55.600391 | Design decision needed | closed | Core (Other) | enhancement | normal | fixed | [patch] Add "in" to the lookup types in the DB API | This patch allows one to do {{{field__in=[1,4,7,10]}}} to select a non-contiguous set of values in a single SELECT statement, which will look like this in SQL: {{{SELECT * FROM table WHERE field IN (1,4,7,10)}}} {{{ Index: django/core/meta.py =================================================================== --- django/core/meta.py (revision 299) +++ django/core/meta.py (working copy) -1018,7 +1020,10 @@ return '%s%s %s %%s' % (table_prefix, field_name, db.OPERATOR_MAPPING[lookup_type]) except KeyError: pass - if lookup_type in ('range', 'year'): + if lookup_type == 'in': + in_clause = ','.join(['%s']*len(value)) + return '%s%s IN (%s)' % (table_prefix, field_name, in_clause) + elif lookup_type in ('range', 'year'): return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name) elif lookup_type in ('month', 'day'): return "%s = %%s" % db.get_date_extract_sql(lookup_type, table_prefix + field_name) -1630,7 +1635,7 @@ "Returns field's value prepared for database lookup." if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'ne', 'month', 'day'): return [value] - elif lookup_type == 'range': + elif lookup_type in ('range', 'in'): return value elif lookup_type == 'year': return ['%s-01-01' % value, '%s-12-31' % value] }}} | adrian | rmunn@pobox.com | 0 | 1 | 0 | 0 | 0 | 0 | ||
172 | 2005-07-24 00:08:57 | 2009-03-30 18:50:55 | 2022-03-06 03:19:56.803914 | Unreviewed | closed | Tools | enhancement | normal | dev | fixed | Twisted (twisted.web2) support for Django | I've implemented a basic module to use Twisted Web2 to drive Django. It's based on the demo.py provided with Twisted.Web2. It retains an MIT license as it's derived from Twisted. ---- {{{ # Copyright (c) 2001-2004 Twisted Matrix Laboratories. # See LICENSE for details. """I am a simple test resource. """ import os.path, os from twisted.web2 import log, wsgi from twisted.internet import reactor # This part gets run when you run this file via: "twistd -noy demo.py" if __name__ == '__builtin__': from twisted.application import service, strports from twisted.web2 import server, vhost, channel #from twisted.internet.ssl import DefaultOpenSSLContextFactory from twisted.python import util # Create the resource we will be serving from django.core.handlers.wsgi import AdminMediaHandler, WSGIHandler os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings.admin' test = wsgi.WSGIResource(AdminMediaHandler(WSGIHandler())) # Setup default common access logging res = log.LogWrapperResource(test) log.DefaultCommonAccessLoggingObserver().start() # Create the site and application objects site = server.Site(res) application = service.Application("demo") # Serve it via standard HTTP on port 8080 s = strports.service('tcp:8080', channel.HTTPFactory(site)) s.setServiceParent(application) # Serve it via HTTPs on port 8081 #s = strports.service('ssl:8081:privateKey=doc/core/examples/server.pem', channel.HTTPFactory(site)) #s.setServiceParent(application) }}} | adrian | jnoetzelman@gmail.com | Twisted dynamic virtual host | 0 | 0 | 0 | 0 | 0 | 0 |
186 | 2005-07-25 01:24:26 | 2007-07-03 23:04:43 | 2022-03-06 03:20:01.420542 | Accepted | closed | Metasystem | enhancement | normal | fixed | [patch] Refactor django/core/meta.py to eliminate duplicate code | The {{{function_get_list}}} and {{{function_get_iterator}}} functions in {{{django/core/meta.py}}} are identical except for their return type. I propose refactoring them by making {{{function_get_list}}} into a simple wrapper around {{{function_get_iterator}}}. | adrian | rmunn@pobox.com | 0 | 1 | 0 | 0 | 0 | 0 | ||
198 | 2005-07-25 21:26:45 | 2007-07-03 23:04:24 | 2022-03-06 03:20:03.741449 | Ready for checkin | closed | Contrib apps | enhancement | critical | magic-removal | fixed | istartswith doesn't work | istartswith is not working. | adrian | brantley (deadwisdom@gmail.com) | database lookup | 0 | 0 | 0 | 0 | 0 | 0 |
200 | 2005-07-25 23:28:37 | 2007-05-21 01:48:27 | 2022-03-06 03:20:04.139840 | Design decision needed | closed | Database layer (models, ORM) | enhancement | normal | fixed | Add a Decimal type and a Currency type | Add a DecimalField type that maps between python's Decimal type and [http://dev.mysql.com/doc/mysql/en/numeric-types.html mySQL's] and [http://www.postgresql.org/docs/8.0/static/datatype.html#DATATYPE-NUMERIC PostgreSQL's] NUMERIC type. I can't make head nor tail of SQLite's type system, but I assume it has some analogue. It should be possible to define the precision and scale of these types, but they should be optional. Add a CurrencyField type which is analogous to a DecimalField limited to two decimal places. Floating point numbers are not good for currency amounts, and I tire of having to convert between an integer number of cents and a string which is in Euro. | adrian | Moof <moof@metamoof.net> | 0 | 0 | 0 | 0 | 0 | 0 | ||
208 | 2005-07-26 14:35:20 | 2007-09-14 15:12:29 | 2022-03-06 03:20:05.499277 | Ready for checkin | closed | Template system | enhancement | normal | dev | fixed | Allow the strings the cycle tag uses to contain spaces | I would like to be able to use the cycle tag like so: {% cycle <td class="tdClass">,</tr><tr><td class="tdClass"> %} The current cycle tag (as I understand it) does not allow spaces or a way to escape spaces. | SmileyChris | anonymous | sprintsept14 | 0 | 1 | 0 | 0 | 0 | 0 |
214 | 2005-07-27 18:20:23 | 2006-08-29 12:11:04 | 2022-03-06 03:20:06.451141 | Unreviewed | closed | Metasystem | enhancement | normal | fixed | [patch] Allow selecting individual fields in SQL SELECT statements via the models API | A common request on IRC recently has been "How do I do SELECT DISTINCT field FROM table"? The models API currently doesn't have any way to allow this: it will only do the equivalent of SELECT *. After discussing this on the django-developers list (http://groups-beta.google.com/group/django-developers/browse_thread/thread/488194de26e0ce18/), I've written a patch to add two functions to the models API at the module level: get_values() and get_values_iterator(). They act exactly like the get_list() and get_iterator() functions, but instead of returning a list (or iterator) of model API objects, they return a list (or iterator) of dictionaries. They also allow a new keyword parameter, "fields", which is a list (or tuple) of field names to return from the SELECT. Thus, with the following patch, doing "SELECT DISTINCT year, month FROM blog ORDER BY year ASC, month ASC" would be written "results = blog.get_values(fields=['year','month'], order_by=['year','month'], distinct=True)". | adrian | rmunn@pobox.com | 0 | 1 | 0 | 0 | 0 | 0 | ||
226 | 2005-07-29 19:29:45 | 2006-10-07 18:55:48 | 2022-03-06 03:20:08.583881 | Unreviewed | closed | Core (Other) | enhancement | normal | invalid | MetaWeblog API Support | It would rock if there was a module to support the MetaWeblog API for manipulating objects. It's a relatively simple XML-RPC standard. It would, for example, allow me to use a nice iPhoto plugin to post photos to my site. (Just a good example.) | adrian | adam@sherman.ca | 0 | 0 | 0 | 0 | 0 | 0 | ||
228 | 2005-07-29 21:27:45 | 2007-07-03 23:04:56 | 2022-03-06 03:20:08.925632 | Accepted | closed | Database layer (models, ORM) | enhancement | normal | fixed | [patch] Better handling of timezones | The timezone-handling in [346] is still too naive: according to http://www.cl.cam.ac.uk/~mgk25/iso-time.html, timezones can be specified in any of the following forms: +hh +hhmm +hh:mm -hh -hhmm -hh:mm I propose the following patch, which can deal with any of these forms. It also saves the timezone data; although we don't currently use it for anything, this patch will make a good jumping-off point in the future if we decide to use it. {{{ Index: django/core/db/typecasts.py =================================================================== --- django/core/db/typecasts.py (revision 346) +++ django/core/db/typecasts.py (working copy) @@ -21,8 +21,16 @@ # "2005-07-29 09:56:00-05" if not s: return None d, t = s.split() - if t[-3] in ('-', '+'): - t = t[:-3] # Remove the time-zone information, if it exists. + # Extract timezone information, if it exists. Currently we just throw + # it away, but in the future we may make use of it. + if '-' in t: + t, tz = t.split('-', 1) + tz = '-' + tz + elif '+' in t: + t, tz = t.split('+', 1) + tz = '+' + tz + else: + tz = '' dates = d.split('-') times = t.split(':') seconds = times[2] }}} | adrian | rmunn@pobox.com | 0 | 1 | 0 | 0 | 0 | 0 | ||
241 | 2005-07-31 20:02:32 | 2006-11-05 14:38:42 | 2022-03-06 03:20:10.879439 | Unreviewed | closed | Core (Other) | enhancement | normal | fixed | Add a django.contrib.markup app | We should add a {{{django.contrib.markup}}} app, which would simply contain template tags to convert between markup languages such as Textile, Markdown, ReST, etc. Here's a patch for a "textile" template filter: {{{ Index: defaultfilters.py =================================================================== --- defaultfilters.py (revision 356) +++ defaultfilters.py (working copy) @@ -416,6 +416,23 @@ from pprint import pformat return pformat(value) +def textile(value, _): + "Generates XHTML from Textile markup developed by Dean Allen" + try: + # Try and import textile + from textile import textile + except ImportError: + # No textile? Just return text again + return value + + try: + value = textile(value) + except: + # Textile doesn't have a good system for rejecting bad input! + pass + + return value + # Syntax: template.register_filter(name of filter, callback, has_argument) template.register_filter('add', add, True) template.register_filter('addslashes', addslashes, False) @@ -452,6 +469,7 @@ template.register_filter('slugify', slugify, False) template.register_filter('stringformat', stringformat, True) template.register_filter('striptags', striptags, False) +template.register_filter('textile', textile, False) template.register_filter('time', time, True) template.register_filter('timesince', timesince, False) template.register_filter('title', title, False) }}} | jacob | django@sharpbanana.co.uk | textile filter template | 0 | 0 | 0 | 0 | 0 | 0 | |
244 | 2005-08-01 16:27:26 | 2005-08-02 20:00:29 | 2022-03-06 03:20:11.435584 | Unreviewed | closed | Metasystem | enhancement | normal | wontfix | [patch] Make new get_values() function more forgiving of mistakes | Thanks for applying my patch from #214! There's one part of it that got omitted, though, and I'm wondering why: it's the part that Does The Right Thing if the user passes a string for the fields=... kwarg. When testing the patch, I found that when I only wanted one field, it was a natural mistake to forget to pass it as a list. I was doing things like "{{{get_values(fields='name', distinct=True}}}" instead of "{{{get_values(fields=['name'], distinct=True}}}". And this was my own code I was calling: if I was making that mistake, others will be also. In the same spirit as [213], I think we should be more forgiving of this mistake: what the user meant is unambiguous, so there's no harm in allowing it. Here's a patch to implement this idea: {{{ Index: django/core/meta.py =================================================================== --- django/core/meta.py (revision 359) +++ django/core/meta.py (working copy) @@ -1100,6 +1100,10 @@ except KeyError: # Default to all fields. fields = [f.name for f in opts.fields] + if isinstance(fields, basestring): + # Be forgiving of mistakes: convert to list + fields = [fields] + cursor = db.db.cursor() _, sql, params = function_get_sql_clause(opts, **kwargs) select = ['%s.%s' % (opts.db_table, f) for f in fields] }}} | adrian | rmunn@pobox.com | 0 | 1 | 0 | 0 | 0 | 0 | ||
247 | 2005-08-02 14:19:20 | 2007-07-03 23:04:54 | 2022-03-06 03:20:11.855299 | Accepted | closed | *.djangoproject.com | enhancement | normal | wontfix | Webpage to list web hosts | It would be useful to have a webpage (preferably Wiki) where web hosts supporting Django can be listed and found. The following is a suggested layout (with supported installation methods in italics) ---- [http://example.com/ Example Host] - Some description about the provider, this can be a paragraph of text so that they can express all the information they wish to. ''mod_python, fcgi'' [http://example.com Lame Host] - Some support for some applications and other stuff that is stuff and that stuff is stuff too. ''cgi'' [http://example.com Boring.net] - Support for nothing but everything and everything that is nothing, except when it isn't. ''mod_snake'' | jacob | Eric Windisch | 0 | 0 | 0 | 0 | 0 | 0 | ||
248 | 2005-08-02 16:22:23 | 2007-07-03 23:04:51 | 2022-03-06 03:20:11.993960 | Unreviewed | closed | Core (Management commands) | enhancement | normal | fixed | Add a "addtopath" command to django-admin.py | django-admin startproject is a great way to start a project, but it doesn't add the project to the python path. As a convenience, there should either be an addtopath command, or installinpython command, or something along those lines, or maybe an option to startproject. This would create a .pth file in site-packages which would have the project's parent directory in it, so that python would pick it up as part of its path. See the documentation for the [http://www.python.org/doc/current/lib/module-site.html site package] for more information on how .pth files work. This has the advantage of being cross-platform, so windows people who have never used a command line don't freak out about having to work out how to set the python path, something that isn't at all obvious, and difficult to do permanently. Plus, it works for python consoles started outside of command lines, which many windows users use. Also, setuptools has a bunch of code showing how to do this, as it's how easy_install goes about installing eggs. You may wish to copy their example of having one "django_sites.pth" file with all the paths to all the sites. As a corollary, maybe a removefrompath command might be a good idea too. | adrian | Moof <moof@metamoof.net> | 0 | 0 | 0 | 0 | 0 | 0 | ||
250 | 2005-08-02 18:07:20 | 2007-03-26 10:42:03 | 2022-03-06 03:20:12.277630 | Unreviewed | closed | Metasystem | enhancement | normal | duplicate | Metasystem needs a BinaryField | The DB cache backend (see #4) is going to require a BinaryField field type. It should probably be considered "for internal use only" and not given an admin interface. | jacob | 0 | 0 | 0 | 0 | 0 | 0 | |||
251 | 2005-08-02 19:41:21 | 2007-07-03 23:04:38 | 2022-03-06 03:20:12.406105 | Accepted | closed | Metasystem | enhancement | normal | fixed | [patch] Add "AND" and "OR" clauses to the SQL query syntax | After discussion on IRC about the undocumented _or syntax, which Adrian didn't like (see http://loglibrary.com/show_page/view/179?Multiplier=3600&Interval=6&StartTime=1122875881 and http://loglibrary.com/show_page/view/179?Multiplier=3600&Interval=6&StartTime=1122989955), a few ideas were tossed around. We ended up settling on having two "magic" functions, tentatively to live in the meta package and be named meta.AND and meta.OR, which will be called as follows: {{{ polls.get_list(pub_date__exact=datetime.now(), clause=meta.OR(question__startswith='a', question__startswith='b')) # Yields "SELECT * FROM polls WHERE pub_date=NOW AND ((question LIKE 'a%') OR (question LIKE 'b%'))" }}} The functions can also be nested: {{{ table.get_list(clause=meta.OR(field1__exact=10, clause=meta.AND(field1__gte=20, field1__lte=29))) # Yields "SELECT * FROM table WHERE field1=10 OR ((field1 >= 20) AND (field1 <= 29))" }}} They can also be invoked multiple times in the same get_list() call. Since you can't repeat exactly the same kwarg twice, anything starting with "clause" will be accepted, thus: {{{ table.get_list(field1__exact=5, clause1=meta.OR(field2__startswith='a', field2__startswith='b'), clause2=meta.OR(field3__startswith='a', field3__startswith='b')) # Yields "SELECT * FROM table WHERE field1=5 AND ((field2 LIKE 'a%') OR (field2 LIKE 'b%')) AND ((field3 LIKE 'a%') OR (field3 LIKE 'b%'))" }}} To avoid any possible conflict with a field name starting with "clause", what follows the word "clause" must be composed of nothing but digits. That way something like "{{{clause__exact='foo'}}}" would still be treated as a search clause, but "{{{clause1=meta.OR(...)}}}" would be treated as an OR. I'll write a patch to implement this idea. | hugo | rmunn@pobox.com | 0 | 1 | 0 | 0 | 0 | 0 | ||
261 | 2005-08-04 10:17:05 | 2005-10-24 01:32:03 | 2022-03-06 03:20:13.915180 | Unreviewed | closed | contrib.admin | enhancement | normal | invalid | the administrator with edit_inline should give ordering choices | Both the ForeignKey() field definition and the generated interface should give possibilities for ordering. Currently it seems like it orders by the ID, but some data might be better ordered by different data. So it would be nice to have a order_list option for ForeignKeys much like we already have for the model classes. | adrian | hugo <gb@bofh.ms> | 0 | 0 | 0 | 0 | 0 | 0 | ||
264 | 2005-08-04 11:04:34 | 2007-07-05 17:35:02 | 2022-03-06 03:20:14.362330 | Ready for checkin | closed | Contrib apps | enhancement | normal | unicode | fixed | None | IP addresses are quite custom values so I think creating a validator for that type would be justified. Here is my take at the problem: {{{ import re IP = re.compile('^\d+\.\d+\.\d+\.\d+$') def isIPAddress(field_data, all_data): if IP.match(field_data): parts = [0 <= int(el) <= 255 for el in field_data.split('.')] if len(parts) == 4: return raise validators.ValidationError("Please enter a dotted number notation for an IP address") }}} | adrian | hugo <gb@bofh.ms> | None | 0 | 0 | 0 | 0 | 0 | 0 |
266 | 2005-08-04 11:27:02 | 2006-10-13 19:47:51 | 2022-03-06 03:20:14.665450 | Unreviewed | closed | Core (Other) | enhancement | normal | fixed | Patch: a validator that matches against another list if some other field has a specific value | This validator will match a field against a list of validators, but only if some other field matches some specific value. Possible usage scenario: a web interface for domain records where A records will require an IP in dotted notation while an CNAME record will require a fully qualified host name. {{{ class MatchesIfOtherFieldEquals: def __init__(self, other_field, other_value, validator_list=[]): self.other_field = other_field self.other_value = other_value self.validator_list = validator_list self.always_test = True def __call__(self, field_data, all_data): if all_data.has_key(self.other_field) and all_data[self.other_field] == self.other_value: for v in self.validator_list: v(field_data, all_data) }}} | adrian | hugo <gb@bofh.ms> | 0 | 0 | 0 | 0 | 0 | 0 | ||
268 | 2005-08-04 13:29:16 | 2006-10-27 19:58:53 | 2022-03-06 03:20:14.981187 | Unreviewed | closed | contrib.admin | enhancement | normal | fixed | Patch: new validator that validates one of many validators | Sometimes one needs to support different formats in a field and for each format there is already a validator. This validator would allow to just say that one of many validators is sufficient for correct data: {{{ class ANY: """ This validator tries all validators. If any one of them succeeds, the validator returns. If none of them succeeds, the given message is thrown as a validation error. The message is rather unspecific, so it's best to give a specific one on instantiation. always_test is propagated from the enclosed validators by setting it if any one of them contains a always_test attribute. """ def __init__(self, validator_list=[], error_message="This field should conform to one of several formats"): self.validator_list = validator_list self.error_message = error_message for v in validator_list: if hasattr(v, 'always_test'): self.always_test = True def __call__(self, field_data, all_data): for v in self.validator_list: try: v(field_data, all_data) return except validators.ValidationError, e: pass raise validators.ValidationError(self.error_message) }}} | adrian | hugo <gb@bofh.ms> | 0 | 0 | 0 | 0 | 0 | 0 | ||
269 | 2005-08-04 13:30:32 | 2006-08-29 12:56:50 | 2022-03-06 03:20:15.149150 | Unreviewed | closed | contrib.admin | enhancement | normal | fixed | Patch: validator that matches against a regular expression | For some cases it's easies to have a validator that just matches against some given regular expression: {{{ class MatchesRegularExpression: def __init__(self, regexp, error_message="The format for this field is wrong"): self.regexp = regexp self.error_message = error_message def __call__(self, field_data, all_data): if not self.regexp.match(field_data): raise validators.ValidationError(self.error_message) }}} This is actually a validator factory that produces the validator on instantiation. | adrian | hugo <gb@bofh.ms> | 0 | 0 | 0 | 0 | 0 | 0 | ||
273 | 2005-08-04 18:51:31 | 2007-07-03 23:05:34 | 2022-03-06 03:20:15.811360 | Accepted | closed | Core (Other) | enhancement | normal | fixed | [patch] Password salt and other algorithms support | The auth_users database table uses a field called password_md5 to hold passwords. However, if found, MD5 hashes can be broken pretty quickly with Rainbow Tables. Could you please consider using SHA-512 encryption instead, perhaps with a varchar(128) field called "password_sha512"? All the best, Dave Hodder | adrian | dmh@dmh.org.uk | 0 | 1 | 0 | 0 | 0 | 0 | ||
280 | 2005-08-05 11:14:58 | 2006-10-27 13:57:35 | 2022-03-06 03:20:16.947218 | Unreviewed | closed | Core (Other) | enhancement | normal | fixed | add _pre_delete and _post_delete hooks | Currently one can define _pre_save and _post_save methods on a model, but no _*_delete methods. It's a useful feature missing, and trivial to implement. Just adding "if hasattr(self, '_pre_delete'): self._pre_delete()" (and the same for _post_delete) to method_delete() on django/core/meta/__init__.py and two paragraphs documenting them on docs/model-api.txt . | jacob | anonymous | 0 | 0 | 0 | 0 | 0 | 0 | ||
286 | 2005-08-08 02:28:09 | 2006-08-29 13:13:53 | 2022-03-06 03:20:17.790552 | Unreviewed | closed | Metasystem | enhancement | normal | fixed | [patch] Eliminate unintuitive behavior when using edit_inline with no core fields specified | Using Django revision 426, Apache+FCGI, MySQL 4.1.11. I created the basic {{{polls}}} and {{{choices}}} models as per the second tutorial: {{{ class Poll(meta.Model): fields = ( meta.CharField('question', maxlength=200), meta.DateTimeField('pub_date', 'date published'), ) admin = meta.Admin( fields = ( (None, {'fields': ('question',)}), ('Date information', {'fields': ('pub_date',), 'classes': 'collapse'}), ) ) def __repr__(self): return self.question class Choice(meta.Model): fields = ( meta.ForeignKey(Poll, edit_inline=True, num_in_admin=3, num_extra_on_change=3), meta.CharField('choice', maxlength=200), meta.IntegerField('votes'), ) def __repr__(self): return self.choice }}} I created a poll in admin interface, with question "What's up?" and no choices for the moment: {{{ >>> from django.models.polls import polls, choices >>> polls.get_list() [What's up?] >>> choices.get_list() [] }}} I added three choices -- "one", "two", and "three" -- in the admin interface, choosing the "Save and continue editing" button: {{{ >>> polls.get_list() [What's up?] >>> p = polls.get_object(question__exact="What's up?") >>> p.get_choice_list() [one, two, three] }}} In MySQL: {{{ mysql> select * from polls_choices ; +----+---------+--------+-------+ | id | poll_id | choice | votes | +----+---------+--------+-------+ | 1 | 1 | one | 0 | | 2 | 1 | two | 0 | | 3 | 1 | three | 0 | +----+---------+--------+-------+ 3 rows in set (0.00 sec) }}} The three choices I just added showed up just fine in the admin interface, along with three blank slots for more choices to be added. I added three more choices -- "four", "five", and "six" -- in the admin interface and clicked "Save and continue editing" again. Suddenly the first three choices disappeared, and only the latest three were showing in the admin interface, in the order "six", "five", and "four". In Python: {{{ >>> p.get_choice_list() [six, five, four] }}} In MySQL: {{{ mysql> select * from polls_choices ; +----+---------+--------+-------+ | id | poll_id | choice | votes | +----+---------+--------+-------+ | 6 | 1 | six | 0 | | 5 | 1 | five | 0 | | 4 | 1 | four | 0 | +----+---------+--------+-------+ 3 rows in set (0.00 sec) }}} Adding more choices in the admin interface should ''add'' to, not ''replace'', the already-existing choices. | adrian | rmunn@pobox.com | 0 | 1 | 0 | 0 | 0 | 0 | ||
288 | 2005-08-08 05:55:46 | 2006-10-22 15:46:59 | 2022-03-06 03:20:18.099830 | Unreviewed | closed | Documentation | enhancement | normal | invalid | Document custom template tags systyem | As far as I could see, there was no way to include userdefined taglibs into a django app except by extending django.templatetags. I might well have missed something, though. Be that as it may, I found it to be quickest to hack django.core.defaulttags to try and load taglibs from paths provided in TEMPLATETAG_DIRS in your config. I'll try to upload the patch here. | jacob | jens@unwesen.de | taglibs | 0 | 0 | 0 | 0 | 0 | 0 | |
294 | 2005-08-09 22:53:23 | 2005-11-09 01:02:08 | 2022-03-06 03:20:19.072397 | Unreviewed | closed | Template system | enhancement | normal | fixed | Use setuptools more aggressively for templates | Locating templates provides the major source of my problems in setting up new django sites from a source checkout. Since most of my templates are closely associated with the python code in the apps it makes sense for me to use setuptools' resource location abilities to find templates. For example in myproject/settings/admin.py: from pkg_resources import resource_filename TEMPLATE_DIRS = ( resource_filename('django.conf', 'admin_templates') ) It would be really nice if this approach was encouraged as it would remove most of the problems for first time users setting up their sites. In fact, if django tried a set of standard locations for templates using resource_filename it should allow people to setup django sites easily just by checking out python modules and adding them to the INSTALLED_APPS. For example myproject/apps/myapp/templates could be a useful default. PS this issue gets a submitter-just-drank-5-pints-of-guinness rating in terms of coherence, try me tomorrow for more elaboration. | adrian | Michael Twomey <micktwomey@gmail.com> | template setuptools | 0 | 0 | 0 | 0 | 0 | 0 | |
296 | 2005-08-10 03:40:26 | 2007-07-03 23:04:59 | 2022-03-06 03:20:19.413518 | Design decision needed | closed | Documentation | enhancement | normal | fixed | [patch] Typo in docs/model_api.txt | The word "deliver" is misspelled in one of the examples. Here's a patch to fix it: {{{ Index: docs/model-api.txt =================================================================== --- docs/model-api.txt (revision 454) +++ docs/model-api.txt (working copy) @@ -87,7 +87,7 @@ object. A add, delete, and change permission is automatically created for each object. This option specifies extra permissions:: - permissions = (("can_delivier_pizzas", "Can deliver pizzas"),) + permissions = (("can_deliver_pizzas", "Can deliver pizzas"),) This is a list of 2-tuples of ``(permission_code, human_readable_permission_name)``. }}} | jacob | rmunn@pobox.com | 0 | 1 | 0 | 0 | 0 | 0 | ||
298 | 2005-08-10 12:32:57 | 2006-10-22 16:03:31 | 2022-03-06 03:20:19.741605 | Unreviewed | closed | Core (Other) | enhancement | normal | wontfix | Need impovement to POST.copy() | When i need to change only few fields of model, for example only date_start field of Project, i need to pass a values of other fields like new_data variable into manipulator.* methods ('coz they are not present in POST) The only place of values of other fields is Project.__dict__ But manipulator.* methods expects new_data.values() like strings. And Project.__dict__ contains .values() like python-values. Also, new_data must be MultiValueDict So, i need to make new_data like this (it's a simple shortened example without checks): {{{ def start(req, p_id): """ Updates "start" information about project Such as start_date, start_people e.t.c. """ try: prj = projects.get_object(pk=rp_id) except projects.ProjectDoesNotExist: raise Http404 manipulator = projects.ChangeManipulator(prj.id) new_data = prj.__dict__ # all fields of Project errors = dict() if req.POST: #only tree fields changed, and values of them are in req.POST new_data = update_post(req.POST.copy(), new_data) errors = manipulator.get_validation_errors(new_data) mnp.do_html2python(new_data) mnp.save(new_data) }}} Where the update_post() is like this: {{{ def update_post(post, data): for key in data: if not key in post.keys(): if data[key]: post[key]=str(data[key]) else: post[key]='' return post }}} But it's easy to say: {{{ new_data = req.POST.copy(new_data) # default values like param #or new_data.update(req.POST) }}} or something like this... | adrian | mr_little | 0 | 0 | 0 | 0 | 0 | 0 | ||
301 | 2005-08-10 17:51:43 | 2005-11-06 22:42:50 | 2022-03-06 03:20:20.266739 | Unreviewed | closed | *.djangoproject.com | enhancement | normal | fixed | Last update on Community page | It would be nice if there was a some information on when the feed's was last parsed. Like planet gnome got: "Updated on August 10, 2005 05:43 PM UTC. Entries are normalised to UTC time." | jacob | espen@grindhaug.org | 0 | 0 | 0 | 0 | 0 | 0 | ||
322 | 2005-08-15 07:57:39 | 2005-08-15 15:24:57 | 2022-03-06 03:20:24.290304 | Unreviewed | closed | contrib.admin | enhancement | normal | fixed | [patch] Admin unavailable in development server after [503] | Just updated from 494 to 503, and now the admin area is unavailable; going to /admin/ gets the following: {{{ There's been an error: Traceback (most recent call last): File "/var/www/django/django_src/django/core/handlers/base.py", line 62, in get_response return callback(request, **param_dict) File "/var/www/django/django_src/django/views/admin/main.py", line 50, in index c = Context(request, {'title': 'Site administration'}) File "/var/www/django/django_src/django/core/extensions.py", line 14, in __init__ self['messages'] = request.user.get_and_delete_messages() File "/var/www/django/django_src/django/models/auth.py", line 128, in get_and_delete_messages for m in self.get_message_list(): AttributeError: 'User' object has no attribute 'get_message_list' }}} This is using Python 2.4.1/MySQL 4.0.23. | adrian | jbennett@roanoke.edu | 0 | 1 | 0 | 0 | 0 | 0 | ||
326 | 2005-08-15 15:42:40 | 2011-11-17 16:06:56 | 2022-03-06 03:20:24.935250 | Accepted | closed | Database layer (models, ORM) | enhancement | normal | 1.0 | wontfix | IPAddressField in decimal format | == An IP address is stored in string format and allocating 15 bytes (120 bits) == But it would be possible convert that address to decimal format and store it in less bits. {{{ >>> import socket, struct >>> ip = "192.168.2.1" >>> q = ip.split(".") >>> n = reduce(lambda a,b: long(a)*256 + long(b), q) >>> n 3232236033L >>> socket.inet_ntoa(struct.pack('!I', n)) '192.168.2.1' }}} [http://groups-beta.google.com/group/comp.lang.python/browse_thread/thread/d4d9d1870a481568/] [http://groups-beta.google.com/group/comp.lang.python/browse_thread/thread/b2e259d7d55a6071/] | adrian | Bless | 0 | 0 | 0 | 0 | 0 | 0 | |
328 | 2005-08-15 20:59:50 | 2006-10-14 14:30:28 | 2022-03-06 03:20:25.267425 | Unreviewed | closed | Core (Other) | enhancement | normal | fixed | [patch] Add a archive_week date-based generic view | I could really use an archive_week generic view or some way to get a similar effect because archive_day is too little and archive_month is too much. just throwing it out there. | adrian | Dagur | generic view archive week | 0 | 1 | 0 | 0 | 0 | 0 | |
341 | 2005-08-17 09:28:06 | 2005-08-19 20:53:45 | 2022-03-06 03:20:28.391521 | Unreviewed | closed | contrib.admin | enhancement | normal | 1.0 | wontfix | unique option | When you use meta.ForeignKey ([] ,unique=True) or a field with 'choices=... ,unique=True' option, it would be well that the select box in form could show us the valid options only. | adrian | Bless | 0 | 0 | 0 | 0 | 0 | 0 | |
342 | 2005-08-17 10:19:26 | 2011-09-28 16:12:23 | 2022-03-06 03:20:28.526863 | Accepted | closed | contrib.admin | enhancement | normal | newforms-admin | fixed | Add a way for fields to be displayed in the admin without being editable | When editable=False option is used then that field isn't showed in the form. But it should be an option for show a field without can to editing it. | brosner | Bless | djangocon | 0 | 1 | 1 | 1 | 0 | 0 |
345 | 2005-08-17 15:38:48 | 2007-07-03 23:05:46 | 2022-03-06 03:20:28.922532 | Accepted | closed | Core (Other) | enhancement | normal | duplicate | Set http Content-type header from settings.py | It would be nice if you could set the default content-type for http-served pages in a settings module somewhere. I'll try to write a patch. | adrian | tim@gerla.net | 0 | 0 | 0 | 0 | 0 | 0 | ||
347 | 2005-08-17 17:09:52 | 2011-08-10 10:51:42 | 2022-03-06 03:20:29.179577 | Unreviewed | closed | Database layer (models, ORM) | enhancement | normal | magic-removal | wontfix | Add setting for table generation to use a default MySQL table type | Allow the MySQL wrapper to create tables with the InnoDB engine, as opposed to just the system default which is typicall MyISAM. MyISAM does not support transactions and does nothing to ensure referential integrity. | adrian | jvoorhis@gmail.com | 0 | 0 | 0 | 0 | 0 | 0 | |
356 | 2005-08-18 11:36:56 | 2006-10-08 00:04:54 | 2022-03-06 03:20:30.283435 | Unreviewed | closed | Core (Other) | enhancement | normal | duplicate | [patch]: simple XML-RPC support for Django | The idea of this patch is to add support to Django for basic XML-RPC capabilities. It works mostly like URL patterns in that there is a ROOT_RPCCONF setting that points to a module that defines a rpc call registry like this: {{{ #!python rpccalls = { 'anton': 'gallery.test.anton', } }}} So the registry is a simple dictionary that maps method names (they can be structured with "." - for example blogger.post) to functions in modules (function "anton" in module gallery.test in this case). Additionally you need to add a mapping for some URL to the rpc view: {{{ #!python urlpatterns = patterns('', (r'^RPC/', 'django.core.rpc.call'), ) }}} The last part is the django.core.rpc module: {{{ #!python import sys import time import xmlrpclib from django.utils.httpwrappers import HttpResponse from django.conf import settings dispatch = {} def call(request): """ This is the view you need to map into your URL space to process RPC calls. """ p, u = xmlrpclib.getparser() p.feed(request.raw_post_data) p.close() args = u.close() method = u.getmethodname() func = dispatch.get(method, None) if func is not None: result = func(*args) xml = xmlrpclib.dumps((result,), methodresponse=1) else: xml = xmlrpclib.dumps(xmlrpclib.Fault(-32601, 'method unknown: %s' % method), methodresponse=1) return HttpResponse(xml, mimetype='text/xml; charset=utf-8') # build the dispatch table for rpc calls out of ROOT_RPCCONF for (fn, fc) in __import__(settings.ROOT_RPCCONF, '', '', ['']).rpccalls.items(): p = fc.rfind('.') modname = fc[:p] funcname = fc[p+1:] dispatch[fn] = getattr(__import__(modname, '', '', ['']), funcname) }}} After setting up all this (django.core.rpc should go into the django source - that's the actual patch), you could use your new RPC call like this: {{{ #!python import xmlrpclib srv = xmlrpclib.Server('http://your.server.here/RPC/') print srv.anton(5,6) print srv.anton('anton','berta') print srv.anton([1,2,3,4],[5,6,7,8}) }}} I think this would allow people for much easier integration of simple XML-RPC webservices into django while keeping the framework idea of django intact. | adrian | hugo <gb@bofh.ms> | 0 | 1 | 0 | 0 | 0 | 0 | ||
357 | 2005-08-18 11:53:53 | 2007-07-03 23:06:01 | 2022-03-06 03:20:30.439216 | Ready for checkin | closed | Core (Management commands) | enhancement | normal | fixed | [patch]: django-admin.py needs a --projects parameter | this parameter is to add stuff to the sys.path environment, so people don't need to either use admin rights to link their projects directory to some python path or use the PYTHONPATH environment variable. {{{ Index: bin/django-admin.py =================================================================== --- bin/django-admin.py (revision 535) +++ bin/django-admin.py (working copy) @@ -52,11 +52,15 @@ parser = DjangoOptionParser(get_usage()) parser.add_option('--settings', help='Python path to settings module, e.g. "myproject.settings.main". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.') + parser.add_option('--projects', + help='Python path to projects directory, e.g. where myproject of "myproject.settings.main" resides. If this isn\'t provided, the PYTHONPATH environment variable will be used.') options, args = parser.parse_args() # Take care of options. if options.settings: os.environ['DJANGO_SETTINGS_MODULE'] = options.settings + if options.projects: + sys.path.insert(0, options.projects) # Run the appropriate action. Unfortunately, optparse can't handle # positional arguments, so this has to parse/validate them. }}} | adrian | hugo <gb@bofh.ms> | 0 | 1 | 0 | 0 | 0 | 0 | ||
376 | 2005-08-20 15:29:27 | 2008-09-06 10:27:28 | 2022-03-06 03:20:33.180679 | Accepted | closed | Core (Other) | enhancement | normal | dev | wontfix | Add a handler for mod_python v. 2 (Django requires v. 3) | I've adapted the mod_python handler to also work on mod_python 2. The differences with the mod_python 3 are fairly small, but it's still somewhat incompatible. In addition, I think you need an index.py file to make it work with the '/' URL given to a basic address. Here's the config I'm using, I'll attach modpython2.py. {{{ <Location /> SetHandler python-program AddHandler python-program .py DirectoryIndex index.py PythonHandler django.core.handlers.modpython2 PythonPath "['/home/dirkjan/dev'] + sys.path" PythonInterpreter weblog.main PythonDebug On SetEnv DJANGO_SETTINGS_MODULE weblog.settings.main </Location> }}} | nobody | Manuzhai | 0 | 1 | 1 | 1 | 0 | 0 | |
378 | 2005-08-21 01:13:02 | 2005-08-21 18:32:42 | 2022-03-06 03:20:33.409868 | Unreviewed | closed | Tools | enhancement | normal | wontfix | django-admin.py should give feedback | I don't want to say "Django should be more like Rails", but the 'rails' script and all of the things in a Rails project's scripts/ directory emit useful feedback which is reassuring at the very least. The django-admin.py script emits nothing unless there is an error - that is, unless it is a command that generates SQL. This can be confusing. My proposal is to at least provide a summary of what is the command does. Another idea: move the sql-generating commands to a separate script. This will help users know what to expect from the admin scripts. | adrian | jvoorhis@gmail.com | django-admin.py | 0 | 0 | 0 | 0 | 0 | 0 | |
384 | 2005-08-21 13:18:08 | 2007-01-17 22:12:17 | 2022-03-06 03:20:34.374450 | Unreviewed | closed | contrib.admin | enhancement | normal | 1.0 | duplicate | A delete button next to 'many' in admin might be more intuitive | As a follow up to my previous report #383, a delete button next to the inline edited items (in the tutorial, the Choices for a particular Poll) would be much cleaner and more intuitive than the 'leave the field blank to delete' approach. Build 541, OS X, Python 2.4.1, MySQL 4.1.12 | adrian | ssteiner | delete, tutorial2, admin | 0 | 0 | 0 | 0 | 0 | 0 |
388 | 2005-08-21 22:08:09 | 2005-08-22 18:25:15 | 2022-03-06 03:20:34.939864 | Unreviewed | closed | Metasystem | enhancement | normal | wontfix | Prefix for django table names | It's mentioned at http://www.djangoproject.com/documentation/legacy_databases/ you can't change the names of the django tables in the database. Proposal: use a prefix, like "_dj_", for all those tables. So you'd have in the database: _dj_sites _dj_packages _dj_content_types etc. This would make browsing your schema easier, since your application-specific schemas wouldn't be interspersed with django-specific metasystem tables in an alphabetical listing. It would also make migrating from legacy databases easier, or interoperation with non-django systems, or indeed any operation that requires direct use of the DB. | adrian | Brendan O'Connor <brenocon@gmail.com> | 0 | 0 | 0 | 0 | 0 | 0 | ||
389 | 2005-08-21 23:09:10 | 2007-01-17 22:12:34 | 2022-03-06 03:20:35.079253 | Unreviewed | closed | contrib.admin | enhancement | normal | invalid | [patch] admin interface only sorts by first ordering field | I have added an ordering attribute to a model with two field names: ordering = ["crate", "card"] I find that get_list() on the model sorts by "crate", then "card", as I expect. However, when I look at the list of objects in the admin interface, it only sorts by "crate" and not both "crate" and "card". | adrian | volsung@mailsnare.net | ordering | 0 | 1 | 0 | 0 | 0 | 0 | |
393 | 2005-08-22 15:36:38 | 2007-02-23 20:52:04 | 2022-03-06 03:20:35.684019 | Ready for checkin | closed | Core (Other) | enhancement | critical | fixed | [patch] Filters don't take the str() value of a var | If I have a category model and do {{category|upper}} it fails, even though i have a __repr__(). Added str() to a number of filters to fix this behaviour. Maybe would be better to add to the template definition what sort of var it should accept? If it only accepts strings, str() everything first within django.core.template[[br]] Also added basic tests to string filters that don't accept args {{{ Index: /usr/local/django_src/django/core/defaultfilters.py =================================================================== --- /usr/local/django_src/django/core/defaultfilters.py (revision 544) +++ /usr/local/django_src/django/core/defaultfilters.py (working copy) @@ -9,7 +9,7 @@ def addslashes(value, _): "Adds slashes - useful for passing strings to JavaScript, for example." - return value.replace('"', '\\"').replace("'", "\\'") + return str(value).replace('"', '\\"').replace("'", "\\'") def capfirst(value, _): "Capitalizes the first character of the value" @@ -19,7 +19,7 @@ def fix_ampersands(value, _): "Replaces ampersands with ``&`` entities" from django.utils.html import fix_ampersands - return fix_ampersands(value) + return fix_ampersands(str(value)) def floatformat(text, _): """ @@ -35,7 +35,7 @@ def linenumbers(value, _): "Displays text with line numbers" from django.utils.html import escape - lines = value.split('\n') + lines = str(value).split('\n') # Find the maximum width of the line count, for use with zero padding string format command width = str(len(str(len(lines)))) for i, line in enumerate(lines): @@ -44,7 +44,7 @@ def lower(value, _): "Converts a string into all lowercase" - return value.lower() + return str(value).lower() def make_list(value, _): """ @@ -55,7 +55,7 @@ def slugify(value, _): "Converts to lowercase, removes non-alpha chars and converts spaces to hyphens" - value = re.sub('[^\w\s-]', '', value).strip().lower() + value = re.sub('[^\w\s-]', '', str(value)).strip().lower() return re.sub('\s+', '-', value) def stringformat(value, arg): @@ -74,7 +74,7 @@ def title(value, _): "Converts a string into titlecase" - return re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title()) + return re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), str(value).title()) def truncatewords(value, arg): """ @@ -93,17 +93,17 @@ def upper(value, _): "Converts a string into all uppercase" - return value.upper() + return str(value).upper() def urlencode(value, _): "Escapes a value for use in a URL" import urllib - return urllib.quote(value) + return urllib.quote(str(value)) def urlize(value, _): "Converts URLs in plain text into clickable links" from django.utils.html import urlize - return urlize(value, nofollow=True) + return urlize(str(value), nofollow=True) def urlizetrunc(value, limit): """ @@ -116,7 +116,7 @@ def wordcount(value, _): "Returns the number of words" - return len(value.split()) + return len(str(value).split()) def wordwrap(value, arg): """ @@ -163,11 +163,11 @@ def linebreaks(value, _): "Converts newlines into <p> and <br />s" from django.utils.html import linebreaks - return linebreaks(value) + return linebreaks(str(value)) def linebreaksbr(value, _): "Converts newlines into <br />s" - return value.replace('\n', '<br />') + return str(value).replace('\n', '<br />') def removetags(value, tags): "Removes a space separated list of [X]HTML tags from the output" @@ -410,7 +410,7 @@ def phone2numeric(value, _): "Takes a phone number and converts it in to its numerical equivalent" from django.utils.text import phone2numeric - return phone2numeric(value) + return phone2numeric(str(value)) def pprint(value, _): "A wrapper around pprint.pprint -- for debugging, really" }}} {{{ Index: /usr/local/django_src/tests/othertests/templates.py =================================================================== --- /usr/local/django_src/tests/othertests/templates.py (revision 544) +++ /usr/local/django_src/tests/othertests/templates.py (working copy) @@ -1,4 +1,4 @@ -from django.core import template, template_loader +from django.core import template, template_loader, defaultfilters # Helper objects for template tests class SomeClass: @@ -10,6 +10,9 @@ def method2(self, o): return o + + def __repr__(self): + return 'DjAnGo' class OtherClass: def method(self): @@ -166,6 +169,25 @@ 'exception04': ("{% extends 'inheritance17' %}{% block first %}{% echo 400 %}5678{% endblock %}", {}, template.TemplateSyntaxError), } +STRING_FILTERS = ( + 'linebreaksbr', + 'striptags', + 'escape', + 'linebreaks', + 'urlize', + 'fix_ampersands', + 'title', + 'capfirst', + 'wordcount', + 'linenumbers', + 'urlencode', + 'lower', + 'upper', + 'phone2numeric', + 'addslashes', + 'slugify' + ) + # This replaces the standard template_loader. def test_template_loader(template_name, template_dirs=None): try: @@ -176,6 +198,8 @@ def run_tests(verbosity=0, standalone=False): template_loader.load_template_source, old_template_loader = test_template_loader, template_loader.load_template_source failed_tests = [] + for stringfilter in STRING_FILTERS: + TEMPLATE_TESTS['filter_' + stringfilter] = ( '{{ var|%s }}' % stringfilter, {"var": SomeClass()}, str(defaultfilters.template.registered_filters[stringfilter][0](str( 'DjAnGo' ), ())) ) tests = TEMPLATE_TESTS.items() tests.sort() for name, vals in tests: }}} | adrian | Boffbowsh | 0 | 1 | 0 | 0 | 0 | 0 | ||
398 | 2005-08-22 21:30:04 | 2007-07-03 23:06:18 | 2022-03-06 03:20:36.424681 | Design decision needed | closed | Template system | enhancement | normal | wontfix | [patch] {%define VAR as%}VALUE{%in%} tag | I submit two patches. The first patch modifies Parser.parse() to optionally pass its parse_until context to the do_* callbacks. This allows template tags to have scopes which are ended implicitly by the end of the enclosing scope. The second patch defines a {% define VAR as %} VALUE {% in %} construct. A typical use is: {{{ {% define title_var as%} {% block title %}The default title{% endblock %} {% in %} <html> <head> <title>{{title_var}}</title> </head> <body> <h1>{{title_var}}</h1> ... }}} Here, by redefining the title block, a template can set the title BOTH in the <head> and the <body> of the page. Many other uses are possible. Note that this is not an attempt to turn the Django template system into a full-fledged programming language, it's just sometimes convenient to declare a name for a value and refer to it later. I have put the define-tag in defaulttags.py because I feel that, as a language construct, defining new variable bindings is at the same level as FOR loops and IF statements. If you do not agree, I hope you will still accept the first patch, because it will allow me to put this define-tag in my own apps and still use them with a standard Django installation. (The define-tag uses the implicit ending feature introduced by the first patch.) | adrian | jvr_django@dory.blub.net | 0 | 1 | 0 | 0 | 0 | 0 | ||
399 | 2005-08-22 21:49:01 | 2011-09-28 16:12:23 | 2022-03-06 03:20:36.553516 | Accepted | closed | Database layer (models, ORM) | enhancement | normal | dev | fixed | Bigint field object needed | The existing IntegerField is not adequate for generating schemas that require a "bigint" field. Either IntegerField needs to take a size/length parameter or a new Field type is necessary. | permon | jmadson@techie.com | sprintsept14, bigint | 0 | 1 | 0 | 0 | 0 | 0 |
409 | 2005-08-23 19:52:54 | 2012-05-11 05:51:30 | 2022-03-06 03:20:38.051861 | Ready for checkin | closed | Database layer (models, ORM) | enhancement | normal | wontfix | Add support for sqlrelay backend, to pool DB connections | A [http://groups-beta.google.com/group/django-users/browse_frm/thread/21ecac21fcbcd0af/6a50bf1c98c4b6c4#6a50bf1c98c4b6c4 discussion] in the mailing list led to sqlrelay as being a good solution to limiting DB connections coming out of Django (among other benefits). I didn't see any activity over here, so I figured I'd open a ticket. | adrian | dustin@spy.net | database sqlrelay sql relay | 0 | 0 | 0 | 0 | 0 | 0 | |
410 | 2005-08-23 20:07:02 | 2007-07-03 23:06:10 | 2022-03-06 03:20:38.228798 | Ready for checkin | closed | Core (Management commands) | enhancement | normal | wontfix | 'django-admin validate' should note when meta.admin.fields is redundant | If {{{meta.admin.fields}}} is redundant, {{{django-admin.py validate}}} should display a notice. | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
419 | 2005-08-26 04:23:46 | 2006-10-22 16:30:00 | 2022-03-06 03:20:39.685299 | Unreviewed | closed | Metasystem | enhancement | enhancement | duplicate | Create meta.AbstractModel | {{{ #!python class BaseModel(meta.Model): foo = meta.CharField(maxlength=200) class FirstChild(BaseModel): bar = meta.CharField(maxlength=10) class SecondChild(BaseModel): bar = meta.CharField(maxlength=10) }}} In this example, {{{BaseModel}}} only exists as an "abstract class" -- its only purpose is to be extended. We don't want to install SQL for it, and we don't want it to be available via the API. So we could introduce a {{{meta.AbstractModel}}} for models that serve this purpose. | adrian | adrian | 0 | 0 | 0 | 0 | 0 | 0 | ||
421 | 2005-08-26 15:54:20 | 2007-07-03 23:06:15 | 2022-03-06 03:20:40.264707 | Design decision needed | closed | Core (Other) | enhancement | normal | fixed | [patch] new events framework | This patch rewrites events framework to the implementation. Instead of old-fashioned ''hooks'', it introduces new term ''listeners'' watching for ''events''. API is quite simple: {{{ >>> from django.core import events >>> >>> def example_listener(event, param=None): ... print '%s -- %s' % (event, param) ... >>> >>> events.add_listener('example_event', example_listener) >>> events.propagate_event('example_event', param='Greets to Brandlay Group') example_event -- Greets to Brandlay Group >>> events.delete_listener('example_event', example_listener) >>> events.propagate_event('example_event', param='Greets to Brandlay Group') >>> }}} Actual hooks ''_pre_save'', ''_post_save'', ''_pre_delete'' and ''_post_delete'' are rewritten to be 'pre_save_%s_%s' % (app_label, module_name), 'post_save_%s_%s' % (app_label, module_name) etc. There are few advantages from new events framework over the current: * '''Hooking all objects, not only models'''. Currently implementation rely only on model events, like ''_pre_save'', ''_post_save'', ''_post_delete'' and other. As I've pointed in #364, there's a lot of scenarios when you want to listen on events not related to models. * '''Queueing listeners'''. Now you can add only one listener on event. With new events framework it's possible to call ''add_listener'' many times adding as many listeners, as you need. * '''Adding and deleting listeners at run-time explicitly'''. You don't have to add new methods to the models. You can call ''add_listener'' at the every line of your code, without need to move objects between layers. Patch: {{{ --- django_src/django/core/events.py 1970-01-01 01:00:00.000000000 +0100 +++ django_src.events/django/core/events.py 2005-08-26 17:40:20.000000000 +0200 @@ -0,0 +1,19 @@ +"Events framework." + +events = {} + +def add_listener(event, listener): + if not events.has_key(event): + events[event] = [] + + events[event].append(listener) + +def delete_listener(event, listener=None): + if not listener: + events[event] = [] + else: + events[event].remove(listener) + +def propagate_event(event, **kwargs): + for listener in events[event]: + listener(event, **kwargs) Files django_src/django/core/events.pyc and django_src.events/django/core/events.pyc differ Files django_src/django/core/exceptions.pyc and django_src.events/django/core/exceptions.pyc differ Files django_src/django/core/formfields.pyc and django_src.events/django/core/formfields.pyc differ Files django_src/django/core/__init__.pyc and django_src.events/django/core/__init__.pyc differ Files django_src/django/core/meta/fields.pyc and django_src.events/django/core/meta/fields.pyc differ diff -urN django_src/django/core/meta/__init__.py django_src.events/django/core/meta/__init__.py --- django_src/django/core/meta/__init__.py 2005-08-26 15:03:29.000000000 +0200 +++ django_src.events/django/core/meta/__init__.py 2005-08-26 16:01:42.000000000 +0200 @@ -766,9 +766,11 @@ return isinstance(other, self.__class__) and getattr(self, opts.pk.column) == getattr(other, opts.pk.column) def method_save(opts, self): + from django.core import events + # Run any pre-save hooks. - if hasattr(self, '_pre_save'): - self._pre_save() + events.propagate_event('pre_save_%s_%s' % (opts.app_label, opts.module_name), model=opts) + non_pks = [f for f in opts.fields if not f.primary_key] cursor = db.db.cursor() @@ -802,15 +804,18 @@ if opts.has_auto_field: setattr(self, opts.pk.column, db.get_last_insert_id(cursor, opts.db_table, opts.pk.column)) db.db.commit() + # Run any post-save hooks. - if hasattr(self, '_post_save'): - self._post_save() + events.propagate_event('post_save_%s_%s' % (opts.app_label, opts.module_name), model=opts) def method_delete(opts, self): + from django.core import events + assert getattr(self, opts.pk.column) is not None, "%r can't be deleted because it doesn't have an ID." + # Run any pre-delete hooks. - if hasattr(self, '_pre_delete'): - self._pre_delete() + events.propagate_event('pre_delete_%s_%s' % (opts.app_label, opts.module_name), model=opts) + cursor = db.db.cursor() for rel_opts, rel_field in opts.get_all_related_objects(): rel_opts_name = opts.get_rel_object_method_name(rel_opts, rel_field) @@ -840,9 +845,9 @@ # delete it from the filesystem. if os.path.exists(file_name) and not opts.get_model_module().get_list(**{'%s__exact' % f.name: getattr(self, f.name)}): os.remove(file_name) + # Run any post-delete hooks. - if hasattr(self, '_post_delete'): - self._post_delete() + events.propagate_event('post_save_%s_%s' % (opts.app_label, opts.module_name), model=opts) def method_get_next_in_order(opts, order_field, self): if not hasattr(self, '_next_in_order_cache'): }}} | adrian | maurycypw@gmail.com | 0 | 1 | 0 | 0 | 0 | 0 | ||
422 | 2005-08-26 16:06:45 | 2005-08-26 16:53:16 | 2022-03-06 03:20:40.716887 | Unreviewed | closed | Core (Other) | enhancement | trivial | duplicate | define a default charset for web pages | On django/utils/httpwrappers.py the DEFAULT_MIME_TYPE is just "text/html". That means the web browsers sometimes show "weird things" when one uses non-ascii characters on the templates (example: customize base_site.html adding some utf-8 characters and open the http://.../admin/ login page). It would be better to define a default charset, changing that to DEFAULT_MIME_TYPE = 'text/html; charset=utf-8' (the same mimetype used on the admin interface). | adrian | anonymous | 0 | 0 | 0 | 0 | 0 | 0 | ||
425 | 2005-08-26 17:13:10 | 2007-07-03 23:06:34 | 2022-03-06 03:20:41.222770 | Accepted | closed | Tools | enhancement | normal | wontfix | django.utils.images should have a thumbnail function | i just taught that django.utils.images should have a function that could create a thumbnail. | adrian | espen@grindhaug.org | 0 | 0 | 0 | 0 | 0 | 0 | ||
428 | 2005-08-27 05:07:28 | 2007-07-03 23:06:03 | 2022-03-06 03:20:41.597097 | Unreviewed | closed | Generic views | enhancement | normal | fixed | [patch] view for serving static files | It would be nice to be able to serve static files from disk while using the test django server. This can be done with a view and urlpattern. I've hacked up an implementation at: http://django.pastebin.com/347411 To use it, put that in your view directory (say in static.py), then add {{{ DOCUMENT_ROOT = '/your/local/document/root/dir' }}} to your settings file, and a pattern: {{{ (r'^(?P<path>.*)$', 'foo.apps.foo.views.static.serve') }}} at the end of your urlpatterns list. This will pick up all the URLs that all the previous patterns couldn't match and try to find them under DOCUMENT_ROOT. Is there any interest in adding this view to the other views django already provides? | jacob | volsung@mailsnare.net | 0 | 1 | 0 | 0 | 0 | 0 | ||
429 | 2005-08-27 22:15:34 | 2005-09-02 18:51:21 | 2022-03-06 03:20:41.726531 | Unreviewed | closed | Core (Other) | enhancement | minor | fixed | Proposed minor cleanup of utils/html.py | The patch attached below makes minor changes to the variable names used for regular expression objects in utils/html.py, for the sake of internal consistency and consistency with other Django modules. The variable names in the patch are lowercase (as they are in core/validators.py and core/defaultfilters.py) and they all now end with "_re" (this was not consistent in html.py, but seems fairly consistent elsewhere). No other modules in the Django distribution appear to reference these names directly. I also edited the module docstring -- it contained what I think was the last reference to World Online in the codebase, and contained three variants of the word "use," which I thought excessive for a single sentence fragment :) | adrian | pb@e-scribe.com | 0 | 0 | 0 | 0 | 0 | 0 | ||
431 | 2005-08-28 12:50:17 | 2005-08-28 14:06:18 | 2022-03-06 03:20:42.050046 | Unreviewed | closed | Template system | enhancement | normal | invalid | Templates should support multiple level of lookups | Let's say I have a dictionary with strings as keys and lists as values, like: {{{ 'dictionary': {'key1': [0, 0], 'key2': [0.25, 0.005076142131979695], 'key3': [0, 0], 'key4': [0, 0]} }}} When I pass that to a template, I would like to access the values of the lists from within the templates, like: {{{ {{ dictionary.key1.0 }} and {{ dictionary.key3.1 }} }}} Additionally, it would be nice to extend {{{for}}} for that: {{{ {% for key, val in dictionary %} ... {% endfor %} }}} I hope you understand what I try to explain. | adrian | lucky@knup.de | 0 | 0 | 0 | 0 | 0 | 0 | ||
433 | 2005-08-29 20:14:37 | 2005-09-02 18:47:25 | 2022-03-06 03:20:42.364462 | Unreviewed | closed | Metasystem | enhancement | normal | duplicate | Add ability to delete multiple objects in a single call | There is a way to retrieve multiple objects using get_list function. There should be also a way to delete multiple objects on a single call. For example {{{ polls.delete(total_votes__lt=10) }}} | adrian | samuel | 0 | 0 | 0 | 0 | 0 | 0 | ||
437 | 2005-08-30 10:25:00 | 2006-10-07 22:05:36 | 2022-03-06 03:20:42.964067 | Unreviewed | closed | Core (Cache system) | enhancement | normal | duplicate | [patch] In memory file cache | Attached to this ticket is a implementation of in memory based file cache. I got basic idea from vampire TemplateCache and re-implemented it to make more general. Usage is simple, if you want to cache a file just call {{{ cache = get_cache('<cache name>') }}} and then {{{ file_contents = cache.load('filename') }}}. It will detect if the file is modified since last access and reload file. I'm currently using it for caching translation objects for Ticket #65. | jacob | nesh <nesh [at] studioquattro [dot] co [dot] yu> | 0 | 1 | 0 | 0 | 0 | 0 | ||
439 | 2005-08-30 17:46:48 | 2006-10-14 14:28:26 | 2022-03-06 03:20:43.270111 | Unreviewed | closed | *.djangoproject.com | enhancement | minor | fixed | Add support info to top of "Create New Ticket" page | This may already be on your list, but I think the Create New Ticket" template could use some links/pointers to support resources -- the mailing lists and IRC, a reminder of the search box and documentation links above, and so on. Hopefully this would reduce the number of "please help me" tickets. I believe the Trac file to modify is templates/newticket.cs. | jacob | pb@e-scribe.com | 0 | 0 | 0 | 0 | 0 | 0 | ||
447 | 2005-09-01 06:55:42 | 2007-01-17 22:12:17 | 2022-03-06 03:20:44.512593 | Unreviewed | closed | contrib.syndication | enhancement | normal | fixed | [PATCH] Add pubdate elements to RSS feeds. | The attached patch adds a get_pubdate_cb to the RSS feed configuration that allows the resulting feed to have pubdate elements. | adrian | benno@jeamland.net | 0 | 0 | 0 | 0 | 0 | 0 | ||
449 | 2005-09-01 15:01:01 | 2006-06-01 03:58:38 | 2022-03-06 03:20:44.845496 | Unreviewed | closed | Template system | enhancement | normal | wontfix | [patch] variable selection for templates should allow negative list indexes | Currently you can access elements of a list by adding the numeric index - but you can only use positive indexes. This should be extended to negative indexes as well, so that you could last elements in lists. | adrian | hugo <gb@bofh.ms> | 0 | 1 | 0 | 0 | 0 | 0 | ||
453 | 2005-09-02 12:00:10 | 2006-10-26 00:38:55 | 2022-03-06 03:20:45.498091 | Unreviewed | closed | Database layer (models, ORM) | enhancement | minor | fixed | Descriptive error messages in django-admin sql/install | It would be very helpful, especially for newer users, to have descriptive error messages when installing/generating SQL for the models. Example - if you don't specify maxlength=x on a CharField, the resulting error is: {{{ Error: projectname couldn't be installed. Possible reasons: * The database isn't running or isn't configured correctly. * At least one of the database tables already exists. * The SQL was invalid. Hint: Look at the output of 'django-admin.py sqlall projectname'. That's the SQL this command wasn't able to run. The full error: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'None) NOT NULL,\n ") }}} The problem is that this tries to create a field of type "varchar ( None )" (Note: This error is on MySQL 4.1.17 - I'm not sure how Postgres/SQLite will handle it, but I'd guess that a "None" will fail there too). A quick look at the code shows that you could do this error checking inside the get_sql_create() function in management.py around line 73 - eg: {{{ if datatype == 'CharField' and rel_field.maxlength == None: print 'Error! "%s" must have a max_length value set' % ( f.column ) }}} However, it's probably not a good idea to pollute management.py with error checking, especially if you want to go the whole route and do complete error checking of all inputs ( eg: check valid parameters for each field type in the database API ). It would be even better if you could distinguish between the error returns: * The database isn't running or isn't configured correctly. * At least one of the database tables already exists. * The SQL was invalid. Surely the error code that's returned by the database handler gives enough information to distinguish? (Currently running SVN 600) | adrian | GrumpySimon | 0 | 0 | 0 | 0 | 0 | 0 | ||
455 | 2005-09-02 23:09:12 | 2006-10-13 21:17:42 | 2022-03-06 03:20:45.782527 | Unreviewed | closed | Core (Other) | enhancement | normal | wontfix | extend formfields.FormWrapper for a readonly mode | It would be cool if the FormWrapper class would accept an optional parameter readonly. If that parameter is True, the FormWrapper shouldn't generate input statements but just the stuff that would go into the value="" attribute of the input statement. This would allow to use the same template for editing data and for showing data if the logged in user doesn't have the right to edit that dataset - and all this without the need of an additional template or too much changes to the editing template. | adrian | hugo <gb@bofh.ms> | 0 | 0 | 0 | 0 | 0 | 0 | ||
460 | 2005-09-04 18:44:14 | 2007-09-18 08:54:52 | 2022-03-06 03:20:46.538605 | Ready for checkin | closed | Database layer (models, ORM) | enhancement | normal | fixed | Patch for get_table_list() for SQLite3 | I've attached a patch for implementation of get_table_list() for SQLite3 in django/core/db/backends/sqlite3.py I'm not sure if any Unicode issues are to be taken care of. {{{ Index: sqlite3.py =================================================================== --- sqlite3.py (revision 618) +++ sqlite3.py (working copy) @@ -119,7 +119,13 @@ return "%i-%02i-%02i 00:00:00" % (dt.year, dt.month, dt.day) def get_table_list(cursor): - raise NotImplementedError + '''See http://www.sqlite.org/faq.html#q9 on how to list all tables in a SQLite database.''' + cursor.execute(''' + SELECT name FROM sqlite_master + WHERE type='table' + ORDER BY name + ''') + return [row[0] for row in cursor.fetchall()] def get_relations(cursor, table_name): raise NotImplementedError }}} Thanks! Swaroop www.swaroopch.info | adrian | Swaroop C H | typo | 0 | 0 | 0 | 0 | 0 | 0 |