#24198 closed Bug (invalid)
Options.get_field behavior change
| Reported by: | Xavier Ordoquy | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 1.8alpha1 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Up to Django 1.7 included Options.get_field would return a FieldDoesNotExist when requested a GenericForeignKey field. However Django 1.8a1 has changed that and get_field now does return it.
If you are interested in fixing this I can provide a test case against Django test suite.
Context:
I started working on the Django REST Framework port to Django 1.8a1. We do have a couple of failing test:
tests/test_relations_generic.py:104: in test_generic_fk
self.assertEqual(serializer.data, expected)
rest_framework/serializers.py:615: in data
ret = super(ListSerializer, self).data
rest_framework/serializers.py:212: in data
self._data = self.to_representation(self.instance)
rest_framework/serializers.py:565: in to_representation
self.child.to_representation(item) for item in iterable
rest_framework/serializers.py:565: in <listcomp>
self.child.to_representation(item) for item in iterable
rest_framework/serializers.py:419: in to_representation
fields = [field for field in self.fields.values() if not field.write_only]
rest_framework/serializers.py:312: in fields
for key, value in self.get_fields().items():
rest_framework/serializers.py:950: in get_fields
model_field.unique_for_date,
E AttributeError: 'GenericForeignKey' object has no attribute 'unique_for_date'
The associated code in the serializers:
for model_field_name, field_name in model_field_mapping.items(): try: model_field = model._meta.get_field(model_field_name) except FieldDoesNotExist: continue unique_constraint_names |= set([ model_field.unique_for_date, model_field.unique_for_month, model_field.unique_for_year ])
As for Django < 1.8, the unique_for_date will never be reached because the get_field would raise a FieldDoesNotExist.
Change History (5)
comment:1 by , 11 years ago
| Summary: | Options.get_field slight behavior change → Options.get_field behavior change |
|---|
comment:2 by , 11 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
follow-up: 4 comment:3 by , 11 years ago
Thanks Tim. I'm sorry I totally missed the migration guide.
comment:4 by , 11 years ago
Replying to xordoquy:
Thanks Tim. I'm sorry I totally missed the migration guide.
Hi,
As Tim confirmed, the new Meta API allows GenericForeignKeys too. If you are concerned this can be an issue on your side, you can easily filter it our using the field flags. It should be the only field that has a one-to-many cardinality without a specific related_model set.
As stated in the guide, related_model can be None if the relation is generic.
Please feel free to contact me on IRC for any issues.
Dan
comment:5 by , 11 years ago
Hi Daniel,
Unfortunately I don't think it is as easy as it sounds. This happened with a GFK, but could be with any field that doesn't inherit from Field.
I didn't read the migration part because I'm not just migrating: I'm supporting Django 1.4 to 1.8. My workaround is there: https://github.com/linovia/django-rest-framework/commit/857185cf07bb539083a90bc75a6dd951da8e2206
I am not sure the field flag you are mentioning was available for 1.4
Anyway, I feel it's kind of a documentation issue but I'm not sure what's the best way to deal with this.
get_field isn't even mentioned in the release notes. I don't think it was part of the public API so I'm not sure it should even be mentioned. However, as the behavior change, I'd assume it is worth adding a notice about this in the backward incompatible change section since its behavior has changed.
This is a backwards incompatible change as described in the migration guide.