A prog2-höz tartozó friss repo anyagok itt elérhetőek: https://git.iit.bme.hu/prog2

You need to sign in or sign up before continuing.
Commit 879c9c92 by Anssi Kääriäinen

Fixed various ForeignObject compatibility issues

Unfortunately it was not possible to use ForeignObject directly
due to Django 1.5 compatibility requirement.
parent ec0a81fd
...@@ -5,7 +5,7 @@ from django.contrib.contenttypes.models import ContentType ...@@ -5,7 +5,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.db.models.fields import Field from django.db.models.fields import Field
from django.db.models.fields.related import ManyToManyRel, RelatedField, add_lazy_relation from django.db.models.fields.related import ManyToManyRel, RelatedField, add_lazy_relation
from django.db.models.related import RelatedObject from django.db.models.related import RelatedObject, PathInfo
from django.utils.text import capfirst from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import six from django.utils import six
...@@ -16,20 +16,46 @@ from taggit.utils import require_instance_manager ...@@ -16,20 +16,46 @@ from taggit.utils import require_instance_manager
class TaggableRel(ManyToManyRel): class TaggableRel(ManyToManyRel):
def __init__(self): def __init__(self, field):
self.related_name = None self.related_name = None
self.limit_choices_to = {} self.limit_choices_to = {}
self.symmetrical = True self.symmetrical = True
self.multiple = True self.multiple = True
self.through = None self.through = None
self.field = field
def get_joining_columns(self):
return self.field.get_reverse_joining_columns()
def get_extra_restriction(self, where_class, alias, related_alias):
return self.field.get_extra_restriction(where_class, related_alias, alias)
class ExtraJoinRestriction(object):
"""
An extra restriction used for contenttype restriction in joins.
"""
def __init__(self, alias, col, content_types):
self.alias = alias
self.col = col
self.content_types = content_types
def as_sql(self, qn, connection):
if len(self.content_types) == 1:
extra_where = "%s.%s = %%s" % (qn(self.alias), qn(self.col))
params = [self.content_types[0]]
else:
extra_where = "%s.%s IN (%s)" % (qn(self.alias), qn(self.col),
','.join(['%s'] * len(self.content_types)))
params = self.content_types
return extra_where, params
class TaggableManager(RelatedField, Field): class TaggableManager(RelatedField, Field):
def __init__(self, verbose_name=_("Tags"), def __init__(self, verbose_name=_("Tags"),
help_text=_("A comma-separated list of tags."), through=None, blank=False): help_text=_("A comma-separated list of tags."), through=None, blank=False):
Field.__init__(self, verbose_name=verbose_name, help_text=help_text, blank=blank) Field.__init__(self, verbose_name=verbose_name, help_text=help_text, blank=blank)
self.through = through or TaggedItem self.through = through or TaggedItem
self.rel = TaggableRel() self.rel = TaggableRel(self)
def __get__(self, instance, model): def __get__(self, instance, model):
if instance is not None and instance.pk is None: if instance is not None and instance.pk is None:
...@@ -98,6 +124,9 @@ class TaggableManager(RelatedField, Field): ...@@ -98,6 +124,9 @@ class TaggableManager(RelatedField, Field):
def m2m_reverse_name(self): def m2m_reverse_name(self):
return self.through._meta.get_field_by_name("tag")[0].column return self.through._meta.get_field_by_name("tag")[0].column
def m2m_reverse_field_name(self):
return self.through._meta.get_field_by_name("tag")[0].name
def m2m_target_field_name(self): def m2m_target_field_name(self):
return self.model._meta.pk.name return self.model._meta.pk.name
...@@ -128,6 +157,72 @@ class TaggableManager(RelatedField, Field): ...@@ -128,6 +157,72 @@ class TaggableManager(RelatedField, Field):
def bulk_related_objects(self, new_objs, using): def bulk_related_objects(self, new_objs, using):
return [] return []
# This and all the methods till the end of class are only used in django >= 1.6
def _get_mm_case_path_info(self, direct=False):
pathinfos = []
linkfield1 = self.through._meta.get_field_by_name('content_object')[0]
linkfield2 = self.through._meta.get_field_by_name(self.m2m_reverse_field_name())[0]
if direct:
join1infos = linkfield1.get_reverse_path_info()
join2infos = linkfield2.get_path_info()
else:
join1infos = linkfield2.get_reverse_path_info()
join2infos = linkfield1.get_path_info()
pathinfos.extend(join1infos)
pathinfos.extend(join2infos)
return pathinfos
def _get_gfk_case_path_info(self, direct=False):
pathinfos = []
from_field = self.model._meta.pk
opts = self.through._meta
object_id_field = opts.get_field_by_name('object_id')[0]
linkfield = self.through._meta.get_field_by_name(self.m2m_reverse_field_name())[0]
if direct:
join1infos = [PathInfo(self.model._meta, opts, [from_field], self.rel, True, False)]
join2infos = linkfield.get_path_info()
else:
join1infos = linkfield.get_reverse_path_info()
join2infos = [PathInfo(opts, self.model._meta, [object_id_field], self, True, False)]
pathinfos.extend(join1infos)
pathinfos.extend(join2infos)
return pathinfos
def get_path_info(self):
if self.use_gfk:
return self._get_gfk_case_path_info(direct=True)
else:
return self._get_mm_case_path_info(direct=True)
def get_reverse_path_info(self):
if self.use_gfk:
return self._get_gfk_case_path_info(direct=False)
else:
return self._get_mm_case_path_info(direct=False)
def get_joining_columns(self, reverse_join=False):
if reverse_join:
return (("id", "object_id"),)
else:
return (("object_id", "id"),)
def get_extra_restriction(self, where_class, alias, related_alias):
extra_col = self.through._meta.get_field_by_name('content_type')[0].column
content_type_ids = [ContentType.objects.get_for_model(subclass).pk
for subclass in _get_subclasses(self.model)]
return ExtraJoinRestriction(related_alias, extra_col, content_type_ids)
def get_reverse_joining_columns(self):
return self.get_joining_columns(reverse_join=True)
@property
def related_fields(self):
return [(self.through._meta.get_field_by_name('object_id')[0],
self.model._meta.pk)]
@property
def foreign_related_fields(self):
return [self.related_fields[0][1]]
class _TaggableManager(models.Manager): class _TaggableManager(models.Manager):
def __init__(self, through, model, instance): def __init__(self, through, model, instance):
...@@ -138,6 +233,9 @@ class _TaggableManager(models.Manager): ...@@ -138,6 +233,9 @@ class _TaggableManager(models.Manager):
def get_query_set(self): def get_query_set(self):
return self.through.tags_for(self.model, self.instance) return self.through.tags_for(self.model, self.instance)
# Django 1.6 renamed this
get_queryset = get_query_set
def _lookup_kwargs(self): def _lookup_kwargs(self):
return self.through.lookup_kwargs(self.instance) return self.through.lookup_kwargs(self.instance)
......
...@@ -8,15 +8,19 @@ from .models import Food, DirectFood, CustomPKFood, OfficialFood ...@@ -8,15 +8,19 @@ from .models import Food, DirectFood, CustomPKFood, OfficialFood
class FoodForm(forms.ModelForm): class FoodForm(forms.ModelForm):
class Meta: class Meta:
model = Food model = Food
fields = '__all__'
class DirectFoodForm(forms.ModelForm): class DirectFoodForm(forms.ModelForm):
class Meta: class Meta:
model = DirectFood model = DirectFood
fields = '__all__'
class CustomPKFoodForm(forms.ModelForm): class CustomPKFoodForm(forms.ModelForm):
class Meta: class Meta:
model = CustomPKFood model = CustomPKFood
fields = '__all__'
class OfficialFoodForm(forms.ModelForm): class OfficialFoodForm(forms.ModelForm):
class Meta: class Meta:
model = OfficialFood model = OfficialFood
fields = '__all__'
...@@ -190,7 +190,6 @@ class TaggableManagerTestCase(BaseTaggingTestCase): ...@@ -190,7 +190,6 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
apple.tags.add("red", "green") apple.tags.add("red", "green")
pear = self.food_model.objects.create(name="pear") pear = self.food_model.objects.create(name="pear")
pear.tags.add("green") pear.tags.add("green")
self.assertEqual( self.assertEqual(
list(self.food_model.objects.filter(tags__name__in=["red"])), list(self.food_model.objects.filter(tags__name__in=["red"])),
[apple] [apple]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment