-
Notifications
You must be signed in to change notification settings - Fork 467
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
170 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
""" | ||
``autocomplete_light.contrib.generic_m2m`` couples django-autocomplete-light | ||
with django-generic-m2m. | ||
Generic many to many are supported since 0.5. It depends on `django-generic-m2m | ||
<http://django-generic-m2m.rtfd.org>`_ external apps. Follow django-generic-m2m | ||
installation documentation, but at the time of writing it barely consists of | ||
adding the ``genericm2m`` to ``INSTALLED_APPS``, and adding a field to models | ||
that should have a generic m2m relation. So, kudos to the maintainers of | ||
django-generic-m2m, fantastic app, use it for generic many to many relations. | ||
See examples in ``test_project/generic_m2m_example``. | ||
""" | ||
from genericm2m.models import RelatedObjectsDescriptor | ||
|
||
from ..generic import GenericForeignKeyField, GenericModelForm | ||
|
||
|
||
class GenericModelForm(GenericModelForm): | ||
""" | ||
Extension of autocomplete_light.GenericModelForm, that handles | ||
genericm2m's RelatedObjectsDescriptor. | ||
""" | ||
|
||
def __init__(self, *args, **kwargs): | ||
""" | ||
Add related objects to initial for each generic m2m field. | ||
""" | ||
super(GenericModelForm, self).__init__(*args, **kwargs) | ||
|
||
for name, field in self.generic_m2m_fields(): | ||
related_objects = getattr(self.instance, name).all() | ||
self.initial[name] = [x.object for x in related_objects] | ||
|
||
def generic_m2m_fields(self): | ||
""" | ||
Yield name, field for each RelatedObjectsDescriptor of the model of | ||
this ModelForm. | ||
""" | ||
for name, field in self.fields.items(): | ||
if not isinstance(field, GenericManyToMany): | ||
continue | ||
|
||
model_class_attr = getattr(self._meta.model, name, None) | ||
if not isinstance(model_class_attr, RelatedObjectsDescriptor): | ||
continue | ||
|
||
yield name, field | ||
|
||
def save(self, commit=True): | ||
""" | ||
Save selected generic m2m relations after saving the model. | ||
""" | ||
model = super(GenericModelForm, self).save(commit) | ||
|
||
for name, field in self.generic_m2m_fields(): | ||
model_attr = getattr(model, name) | ||
selected_relations = self.cleaned_data.get(name, []) | ||
|
||
for related in model_attr.all(): | ||
if related.object not in selected_relations: | ||
model_attr.remove(related) | ||
|
||
for related in selected_relations: | ||
model_attr.connect(related) | ||
|
||
return model | ||
|
||
|
||
class GenericManyToMany(GenericForeignKeyField): | ||
""" | ||
Simple form field that converts strings to models. | ||
""" | ||
def prepare_value(self, value): | ||
if hasattr(value, '__iter__'): | ||
return [super(GenericManyToMany, self).prepare_value(v) \ | ||
for v in value] | ||
return super(GenericManyToMany, self).prepare_value(value) | ||
|
||
def to_python(self, value): | ||
if hasattr(value, '__iter__'): | ||
return [super(GenericManyToMany, self).to_python(v) for v in value] | ||
return super(GenericManyToMany, self).to_python(value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,52 @@ | ||
Generic relations support | ||
GenericForeignKey support | ||
========================= | ||
|
||
Generic foreign keys are supported since 0.4. | ||
|
||
Example | ||
------- | ||
|
||
Such a form: | ||
GenericChannelBase | ||
------------------ | ||
|
||
.. literalinclude:: ../../test_api_project/project_specific/generic_form_example.py | ||
:language: python | ||
.. automodule:: autocomplete_light.channel.generic | ||
:members: | ||
|
||
Would work with such a channel: | ||
Example | ||
~~~~~~~ | ||
|
||
.. literalinclude:: ../../test_api_project/project_specific/generic_channel_example.py | ||
:language: python | ||
|
||
Form | ||
---- | ||
GenericForeignKeyField | ||
---------------------- | ||
|
||
.. automodule:: autocomplete_light.generic | ||
:members: | ||
|
||
Channel | ||
------- | ||
Example | ||
~~~~~~~ | ||
|
||
.. automodule:: autocomplete_light.channel.generic | ||
.. literalinclude:: ../../test_api_project/project_specific/generic_form_example.py | ||
:language: python | ||
|
||
GenericManyToMany | ||
----------------- | ||
|
||
.. automodule:: autocomplete_light.contrib.generic_m2m | ||
:members: | ||
|
||
Example | ||
~~~~~~~ | ||
|
||
Example model with ``related``: | ||
|
||
.. literalinclude:: ../../test_project/generic_m2m_example/models.py | ||
:language: python | ||
|
||
Example ``generic_m2m.GenericModelForm`` usage: | ||
|
||
.. literalinclude:: ../../test_project/generic_m2m_example/forms.py | ||
:language: python | ||
|
||
Example ``ModelAdmin``: | ||
|
||
.. literalinclude:: ../../test_project/generic_m2m_example/admin.py | ||
:language: python |
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from django.contrib import admin | ||
|
||
from models import ModelGroup | ||
from forms import ModelGroupForm | ||
|
||
|
||
class ModelGroupAdmin(admin.ModelAdmin): | ||
form = ModelGroupForm | ||
admin.site.register(ModelGroup, ModelGroupAdmin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import autocomplete_light | ||
from autocomplete_light.contrib.generic_m2m import GenericModelForm, \ | ||
GenericManyToMany | ||
|
||
from models import ModelGroup | ||
|
||
|
||
class ModelGroupForm(GenericModelForm): | ||
related = GenericManyToMany( | ||
widget=autocomplete_light.AutocompleteWidget('MyGenericChannel')) | ||
|
||
class Meta: | ||
model = ModelGroup |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from django.db import models | ||
from django.db.models import signals | ||
from django.contrib.contenttypes import generic | ||
|
||
from genericm2m.models import RelatedObjectsDescriptor | ||
|
||
class ModelGroup(models.Model): | ||
name = models.CharField(max_length=100) | ||
|
||
related = RelatedObjectsDescriptor() | ||
|
||
def __unicode__(self): | ||
return self.name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters