Here is my model
class RecipeIngredient(models.Model):
recipe = models.ForeignKey(Recipe)
ingredient = models.ForeignKey(Ingredient)
serving_size = models.ForeignKey(ServingSize)
quantity = models.IntegerField()
order = models.IntegerField()
created = models.DateTimeField(auto_now_add = True)
updated = models.DateTimeField(auto_now = True)
and my model form
class RecipeIngredientForm(forms.ModelForm):
recipe_ingredient = forms.CharField()
class Meta:
model = RecipeIngredient
widgets = {
'serving_size' : forms.Select(attrs={'class' : 'test'}),
'recipe_ingredient' : forms.TextInput(),
}
I get the following error when I navigate to the page
Unhandled exception in thread started by <function inner_run at 0x1010faf50>
Traceback (most recent call last):
File "/Library/Python/2.6/site-packages/django/core/management/commands/runserver.py", line 48, in inner_run
self.validate(display_num_errors=True)
File "/Library/Python/2.6/site-packages/django/core/management/base.py", line 245, in validate
num_errors = get_validation_errors(s, app)
File "/Library/Python/2.6/site-packages/django/core/management/validation.py", line 28, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "/Library/Python/2.6/site-packages/django/db/models/loading.py", line 146, in get_app_errors
self._populate()
File "/Library/Python/2.6/site-packages/django/db/models/loading.py", line 61, in _populate
self.load_app(app_name, True)
File "/Library/Python/2.6/site-packages/django/db/models/loading.py", line 78, in load_app
models = import_module('.models', app_name)
File "/Library/Python/2.6/site-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/models.py", line 128, in <module>
RecipeIngredientFormSet = inlineformset_factory(Recipe, RecipeIngredient, extra=1, form=RecipeIngredientForm)
File "/Library/Python/2.6/site-packages/django/forms/models.py", line 838, in inlineformset_factory
FormSet = modelformset_factory(model, **kwargs)
File "/Library/Python/2.6/site-packages/django/forms/models.py", line 669, in modelformset_factory
formfield_callback=formfield_callback)
File "/Library/Python/2.6/site-packages/django/forms/models.py", line 407, in modelform_factory
return ModelFormMetaclass(class_name, (form,), form_class_attrs)
File "/Library/Python/2.6/site-packages/django/forms/models.py", line 220, in __new__
opts.exclude, opts.widgets, formfield_callback)
File "/Library/Python/2.6/site-packages/django/forms/models.py", line 178, in fields_for_model
formfield = formfield_callback(f, **kwargs)
TypeError: <lambda>() got an unexpected keyword argument 'widget'
but if I remove this line from my RecipeIngredientForm the error goes away
'serving_size' : forms.Select(attrs={'class' : 'test'}),
Any ideas whatI did wrong?
Just don't add Select widget to this field, it's ModelChoiceField, and is rendered as select box anyway. If you put Select widget on ModelChoiceField, it won't render properly (will show unicode output in value rather than ID).
Also you don't need the first CharField unless you want a text input with auto-completion.
To show the input element with custom attributes, use {% field %} tag:
{% field myform.myselect class="XYZ" %}
renders it to
<select name="..." class="XYZ">...
I think you'll agree that it's a bad idea to customize classes and templates inside forms or models. It makes it impossible to debug templates.
I ran into a similar problem.
I specified a custom "form" kwarg in a modelformset_factory constructor. This would consistently fail with the error you describe while that form class had custom widgets specified in its meta class:
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'myField' : forms.fields.TextInput(attrs={'readonly':'readonly'}),
}
MyFormFactory = modelformset_factory(MyModel,form=MyForm)
Changing the form class to specify custom widgets in the init method seemed to solve this:
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self,*args,**kwargs):
self.fields['myField'].widget = forms.fields.TextInput(attrs={'readonly':'readonly'})
Related
Given the following code:(don't mind the Fields there're just for illustration)
Models
class UserModel(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
Fields
class CommonInfo(models.Model):
delete = models.BooleanField(default=False)
Fields
class MyModel(CommonInfo, UserModel):
my_name = models.CharField(max_length=50, blank=False, null=False)
Fields
Serializer
class MySerializer(views.APIView):
class Meta:
model = MyModel
fields = '__all__'
Views
class MyViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MySerializer
URLs
router.register(r'studio', MyViewSet, basename='studio')
This upside model, Serializer & Views use. I use in Django REST Framework. but when I call MyModel they give me an error.
Return the following error when API call:
init() takes 1 positional argument but 2 were given
Error stack
Internal Server Error: /studio/
Traceback (most recent call last):
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/rest_framework/viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/rest_framework/mixins.py", line 45, in list
serializer = self.get_serializer(queryset, many=True)
File "/home/chetan/Workspace/PhotoLab/PhotoLab/venv/lib/python3.8/site-packages/rest_framework/generics.py", line 110, in get_serializer
return serializer_class(*args, **kwargs)
TypeError: __init__() takes 1 positional argument but 2 were given
[21/Mar/2021 13:15:33] "GET /studio/ HTTP/1.1" 500 99610
You are inheriting from APIView for you MySerializer class.
to fix that, inherit from ModelSerializer from Django rest framework serializers
from rest_framework import serializers
class MySerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
and everything should be resolved.
I'm tasked with upgrading a Django REST framework project from Django 1.8 to Django 2.x. I already ported the whole code from python 2.7 to python 3.7 and from Django 1.8 to 2.0.13. I'm using virtual envs.
I got it running on python 3.7 and Django 2.0.13, and RESTframework 3.11, although I ran into problems while trying to create new objects.
Here's the Traceback to my problem:
Traceback (most recent call last):
File "C:\Users\user1\Envs\projpy3\lib\site-packages\django\core\handlers\exception.py", line 35, in inner
response = get_response(request)
File "C:\Users\user1\Envs\projpy3\lib\site-packages\django\core\handlers\base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\user1\Envs\projpy3\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\user1\Envs\projpy3\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\user1\projects\proj_py3\rest_framework\viewsets.py", line 114, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\user1\projects\proj_py3\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\user1\projects\proj_py3\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\user1\projects\proj_py3\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "C:\Users\user1\projects\proj_py3\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\user1\projects\proj_py3\rest_framework\mixins.py", line 18, in create
serializer.is_valid(raise_exception=True)
File "C:\Users\user1\projects\proj_py3\rest_framework\serializers.py", line 219, in is_valid
self._validated_data = self.run_validation(self.initial_data)
File "C:\Users\user1\projects\proj_py3\rest_framework\serializers.py", line 418, in run_validation
value = self.to_internal_value(data)
File "C:\Users\user1\projects\proj_py3\rest_framework\serializers.py", line 471, in to_internal_value
for field in fields:
File "C:\Users\user1\projects\proj_py3\rest_framework\serializers.py", line 354, in _writable_fields
for field in self.fields.values():
File "C:\Users\user1\Envs\projpy3\lib\site-packages\django\utils\functional.py", line 36, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Users\user1\projects\proj_py3\rest_framework\serializers.py", line 348, in fields
for key, value in self.get_fields().items():
File "C:\Users\user1\projects\proj_py3\rest_framework\serializers.py", line 1027, in get_fields
field_names = self.get_field_names(declared_fields, info)
File "C:\Users\user1\projects\proj_py3\rest_framework\serializers.py", line 1128, in get_field_names
serializer_class=self.__class__.__name__
AssertionError: The field 'participantIDs' was declared on serializer OrderSerializer, but has not been included in the 'fields' option.
I don't understand why that exception only occurs in the new version of the code, since I didn't change the models, serializers, or views, aside from the version updates.
this is what the problematic serializer looks like:
class OrderSerializer(serializers.ModelSerializer):
created_by = ShortPersonSerializer(read_only=True, required=False)
modified_by = ShortPersonSerializer(read_only=True, required=False)
customer = OrderPersonSerializer(required=False, allow_null=True, partial=True)
...
...
participantIDs = serializers.SlugRelatedField(many=True, required=False, allow_null=True, slug_field='id', source='participants', queryset=Person.objects.all())
...
...
class Meta:
model = Order
fields = ('id', 'title','customer',
'customer_copy_id', 'customer_copy_salutation', 'customer_copy_first_name', 'customer_copy_last_name', 'created_at', 'created_by', 'modified_at', 'modified_by')
def create(self, validated_data):
customer_data = validated_data.pop('customer', None)
participants_data = validated_data.pop('participants', None)
if customer_data and customer_data is not None:
validated_data['customer'] = Person(pk=customer_data['id'])
order = Order.objects.create(**validated_data)
if participants_data and participants_data is not None:
setattr(order, 'participants', participants_data) # line 1
order.save() # line 2
...
Additional info:
Before this error was detected, I got a different error, with the following traceback:
Traceback (most recent call last):
...
...
File "C:\Users\user1\projects\proj_py3\rest_framework\serializers.py", line 204, in save
self.instance = self.create(validated_data)
File "C:\Users\user1\projects\proj_py3\orders\serializers.py", line 90, in create
setattr(order, 'participants', participants_data)
File "C:\Users\user1\Envs\projpy3\lib\site-packages\django\db\models\fields\related_descriptors.py", line 509, in __set__
% self._get_set_deprecation_msg_params(),
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use participants.set() instead.
so I had changed the serializer like this:
...
...
if participants_data and participants_data is not None:
#setattr(order, 'participants', participants_data) # line 1
order.save() # line 2
order.participants.set(participants_data)
...
ever since I've done that, I get the AssertionError instead of the TypeError, and I don't know how to revert that problem. Ofcourse I changed the code back, but I've also deleted all the compiled files in the project directory, I deleted the virtual env and created a new one, I ran a disk cleanup on Windows, I even uninstalled Python37 in order to install it again. Always rebooting inbetween. All to no avail.
UPDATE:
I compared the update and create methods in my project's serializers.py files with the ones in rest_framework version I'm using: rest_framework/serializers.py on GitHub
I changed them according to the newer version of the Django REST framework (the code was developed for an older version).
I also checked all the serializers of the other Apps in the project, and I found out, that all but the concerned App orders had the attribute participantsID in their Serializer's Meta class, in case it's supposed to access the other App through the other's Serializer.
In that case, it's like suggested in the comments: the AssertionError was there all along.
There is nothing else to do but to add the attribute to fields.
Add participantIDs to your fields attribute of OrderSerializer's Meta class
class OrderSerializer(serializers.ModelSerializer):
# other code snippets
class Meta:
model = Order
fields = (other-fields, 'participantIDs')
# other code snippets
I am trying to restify my backend using django-rest-gis, in such a way that POST request adds data to database and GET request lists down the data. However, I am getting following error:-
Internal Server Error: /api/
Traceback (most recent call last):
File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/generics.py", line 241, in get
return self.list(request, *args, **kwargs)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/mixins.py", line 48, in list
return Response(serializer.data)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework_gis/serializers.py", line 20, in data
return super(ListSerializer, self).data
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 262, in data
self._data = self.to_representation(self.instance)
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework_gis/serializers.py", line 28, in to_representation
("features", super(GeoFeatureModelListSerializer, self).to_representation(data))
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 686, in to_representation
self.child.to_representation(item) for item in iterable
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 686, in <listcomp>
self.child.to_representation(item) for item in iterable
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework_gis/serializers.py", line 100, in to_representation
fields = list(self.fields.values())
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 363, in fields
for key, value in self.get_fields().items():
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 1031, in get_fields
field_names, declared_fields, extra_kwargs
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 1378, in get_uniqueness_extra_kwargs
field_names, declared_fields, extra_kwargs
File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 1450, in _get_model_fields
if field_name in declared_fields:
TypeError: unhashable type: 'list'
[25/May/2019 04:48:29] "GET /api/ HTTP/1.1" 500 147185
I have followed many answers on stackoverflow but could only get that it comes when you have a mutable type as key in dictionary
models.py
from django.contrib.gis.db import models
# Create your models here.
class test1(models.Model):
date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
location = models.PointField(blank=False)
plg = models.PolygonField(srid=4326, geography=True, null=True, blank=True)
city = models.CharField(max_length=50, blank=False)
state = models.CharField(max_length=50, blank=False)
def __str__(self):
return "%s" % (self.state)
serializers.py
from rest_framework_gis.serializers import GeoFeatureModelSerializer
from .models import test1
class test1Serializer(GeoFeatureModelSerializer):
class Meta:
model = test1
geo_field = ['location','plg']
auto_bbox = True
id_field = False
fields = ('city','state')
views.py
from .models import test1
from .serializers import test1Serializer
from rest_framework.generics import ListCreateAPIView
class test1SerializerCreate(ListCreateAPIView):
serializer_class = test1Serializer
queryset = test1.objects.all()
GeoFeatureModelSerializer only takes one field and it doesn't take the list, check with one field and it should work. Use Rest for multiple fields and you can parse in views. Or you can make a new GeometrySerializerMethodField field and return two geometry in that
geo_field cannot be list.
It can be this way:
class test1Serializer(GeoFeatureModelSerializer):
m_geo_field = GeometrySerializerMethodField()
def get_m_geo_field(self, obj):
return # do whatever you like
class Meta:
model = Location
geo_field = 'm_geo_field'
I'm using sessions in a current django project and recently got a 'Object of type 'date' is not JSON serializable' error - due to the move_in_date field below.
When saving a modelform of the below model to the session via:
if form.is_valid():
request.session.update(form.cleaned_data)
my model:
class Address(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
house_name_number = models.CharField(max_length=255, verbose_name="house name or number")
street_name = models.CharField(max_length=255)
town_city = models.CharField(max_length=255)
county = models.CharField(max_length=255)
postcode = models.CharField(max_length=8)
same_address = models.BooleanField()
move_in_date = models.DateField(null=True, blank=True)
I've tried to solve the issue by using DjangoJSONEncoder as suggested by the docs, which can handle datetimes via the settings with SESSION_SERIALIZER=DjangoJSONEncoder (should this be a serializer rather than an encoder?), but trying that or SESSION_SERIALIZER=PickleSerializer both give an Attribute error - ... has no attribute 'rsplit'
Additionally I was using django wizard before which stores intermediate data (such as the field causing the date issue above) in the session. I've now switched that part of the app to use seperate views for flexibility (as signup wasn't just a linear path), django wizard doesn't have this issue, how does it get round this?
Updated with stacktrace
Traceback (most recent call last):
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/utils/deprecation.py", line 142, in __call__
response = self.process_response(request, response)
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/middleware.py", line 58, in process_response
request.session.save()
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py", line 83, in save
obj = self.create_model_instance(data)
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py", line 69, in create_model_instance
session_data=self.encode(data),
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py", line 98, in encode
serialized = self.serializer().dumps(session_dict)
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/core/signing.py", line 93, in dumps
return json.dumps(obj, separators=(',', ':')).encode('latin-1')
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'date' is not JSON serializable
Stack trace for trying DjangoJSONEncoder:
Traceback (most recent call last):
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/utils/deprecation.py", line 138, in __call__
response = self.process_request(request)
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/middleware.py", line 20, in process_request
request.session = self.SessionStore(session_key)
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py", line 18, in __init__
super(SessionStore, self).__init__(session_key)
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py", line 51, in __init__
self.serializer = import_string(settings.SESSION_SERIALIZER)
File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/utils/module_loading.py", line 15, in import_string
module_path, class_name = dotted_path.rsplit('.', 1)
AttributeError: type object 'DjangoJSONEncoder' has no attribute 'rsplit'
A few things of confusion are hitting you:
When setting the serializer, do not provide a class reference, but a dotted part. This is seen in the error:
module_path, class_name = dotted_path.rsplit('.', 1)
DjangoJSONEncoder isn't the right fix for a serializer. It is referenced in the documentation as a way to serialize models before putting them into the session.
If you want to make a smart serializer then you still need to create a Serializer, which should support a dumps and loads interface, that leverage a JsonEncoder and JsonDecoder respectively.
The Pickle serializer will work just fine, but as said you need to provide the dotted path.
If you want to use JSON as serializer, then this might be a good start:
from django.core.serializers.json import DjangoJSONEncoder
from django.core.signing import JSONSerializer as BaseJSONSerializer
class SmartJSONSerializer(BaseJSONSerializer):
def dumps(self, obj):
return json.dumps(obj, separators=(',', ':'), cls=DjangoJSONEncoder).encode('latin-1')
I'm trying to use generic foreign keys, but I can't seem to get them to work properly.
First, some context: I've got a messaging app and a groups app. Now, I want to be able to have players/groups write pms (private messages) to other users/groups. Here's my Pm model:
class Pm(models.Model):
"""Represents a private message (a la email) from one user to another."""
title = models.CharField(max_length=settings.max_title_length, default="(Blank)")
slug = models.SlugField(max_length=settings.max_title_length, editable=False)
#This was my code from when I only allowed pms to go from user to another
#user
#author = models.ForeignKey(Player, related_name="written_messages")
#recipient = models.ForeignKey(Player, related_name="recieved_messages")
text = models.TextField(max_length=settings.max_post_length)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
#Both will be either a group or a player
author = generic.GenericForeignKey('content_type', 'object_id')
recipient = generic.GenericForeignKey('content_type', 'object_id')
#[snip]
and here's the relevant bits of my Group and Player models:
class Group(models.Model):
#[snip]
written_messages = generic.GenericRelation("messaging.Pm")
sent_messages = generic.GenericRelation("messaging.Pm")
class Player(My_Model):
user = models.OneToOneField(User)
#[snip]
written_messages = generic.GenericRelation("messaging.Pm")
sent_messages = generic.GenericRelation("messaging.Pm")
Does this look correct?
When I run it, I get this traceback (so obviously something's wrong):
Traceback (most recent call last):
File "/usr/local/lib/python3.2/dist-packages/django/core/urlresolvers.py", line 339, in urlconf_module
return self._urlconf_module
AttributeError: 'RegexURLResolver' object has no attribute '_urlconf_module'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.2/wsgiref/handlers.py", line 137, in run
self.result = application(self.environ, self.start_response)
File "/usr/local/lib/python3.2/dist-packages/django/contrib/staticfiles/handlers.py", line 72, in __call__
return self.application(environ, start_response)
File "/usr/local/lib/python3.2/dist-packages/django/core/handlers/wsgi.py", line 180, in __call__
self.load_middleware()
File "/usr/local/lib/python3.2/dist-packages/django/core/handlers/base.py", line 49, in load_middleware
mw_instance = mw_class()
File "/usr/local/lib/python3.2/dist-packages/django/middleware/locale.py", line 24, in __init__
for url_pattern in get_resolver(None).url_patterns:
File "/usr/local/lib/python3.2/dist-packages/django/core/urlresolvers.py", line 346, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/usr/local/lib/python3.2/dist-packages/django/core/urlresolvers.py", line 341, in urlconf_module
self._urlconf_module = import_module(self.urlconf_name)
File "/usr/local/lib/python3.2/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/home/mark/Dropbox/Public/Galcon/galcon/galcon/urls.py", line 40, in <module>
("^messages/", include("messaging.urls")),
File "/usr/local/lib/python3.2/dist-packages/django/conf/urls/__init__.py", line 26, in include
urlconf_module = import_module(urlconf_module)
File "/usr/local/lib/python3.2/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/home/mark/Dropbox/Public/Galcon/galcon/messaging/urls.py", line 3, in <module>
from . import views
File "/home/mark/Dropbox/Public/Galcon/galcon/messaging/views.py", line 10, in <module>
from . import my_forms
File "/home/mark/Dropbox/Public/Galcon/galcon/messaging/my_forms.py", line 5, in <module>
class Modify_Message_Form(forms.ModelForm):
File "/usr/local/lib/python3.2/dist-packages/django/forms/models.py", line 283, in __new__
raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (recipient) specified for Pm
The mentioned form is pretty simple:
class Modify_Message_Form(forms.ModelForm):
class Meta:
model = Pm
fields = ["title", "recipient", "text"]
What have I done wrong? Thanks!
Using the name of the GenericForeignKey in the form doesn't work as it's not actually a real field but more of a convenience. There's no widget to display the relationship; you usually display the content_type and object_id. If you want to see the relationship in the admin interface then I'd recommend looking at Grappelli.
You also need content_type and object_id fields for each GenericForeignKey.
author_content_type = models.ForeignKey(ContentType)
author_object_id = models.PositiveIntegerField()
recipient_content_type = models.ForeignKey(ContentType)
recipient_object_id = models.PositiveIntegerField()
author = generic.GenericForeignKey('author_content_type', 'author_object_id')
recipient = generic.GenericForeignKey('recipient_content_type', 'recipient_object_id')
I've not much experience with GenericRelations but from what I know you'd also need to specify the content_type and object_id fields in your Player and Group models.
written_messages = generic.GenericRelation(messaging.Pm
content_type_field='author_content_type',
object_id_field='author_object_id')
It seems, by looking at the traceback, that you cannot use GenericForeignKeys as form fields. But I think you can use recipient_content_type and recipient_content_id instead, which is what Django admin usually shows to users.