I'm trying to use multiupload in django form for upload several images at once.
I'm using django ModelForm but when i'm calling form.is_valid() in function-base view or using generic.FormView, i'm getting 'list' object has no attribute 'name' error. in generic.FormView neither of form_valid and form_invalid methods aren't called. although when I use request.POST.get(some_data) it works without any errors but I want to use generic.FormView for some validations. I think the validation of the form makes the error happen.
so what should I do?
here is my code.
models.py
class Post(models.Model):
post_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name="posts")
text = models.TextField(max_length=1000)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
...
class Image(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="images")
image = models.ImageField(upload_to="images/posts/")
forms.py
class PostForm(forms.ModelForm):
images = MultiImageField(min_num=1, max_num=3)
class Meta:
model = models.Post
fields = ("text", "images")
views.py
class CreatePostView(LoginRequiredMixin, generic.FormView):
template_name = "posts/post_create.html"
form_class = forms.PostForm
def get_success_url(self):
return redirect("profile", slug=self.request.kwargs.slug)
def form_valid(self, form):
...
# some codes
...
return super(CreatePostView, self).form_valid(form)
error:
Traceback (most recent call last):
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\contrib\auth\mixins.py", line 73, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\base.py", line 119, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\edit.py", line 152, in post
if form.is_valid():
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\forms.py", line 205, in is_valid
return self.is_bound and not self.errors
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\forms.py", line 200, in errors
self.full_clean()
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\forms.py", line 433, in full_clean
self._clean_fields()
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\forms.py", line 443, in _clean_fields
value = field.clean(value, bf.initial)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\fields.py", line 670, in clean
return super().clean(data)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\fields.py", line 200, in clean
self.run_validators(value)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\fields.py", line 185, in run_validators
v(value)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\validators.py", line 611, in validate_image_file_extension
return FileExtensionValidator(allowed_extensions=get_available_image_extensions())(
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\validators.py", line 576, in __call__
extension = Path(value.name).suffix[1:].lower()
Exception Type: AttributeError at /profile/ehsanadmin/post/create/
Exception Value: 'list' object has no attribute 'name'
Related
I am trying to learn how to add a 2nd Context to a Class-Based view which has always been an issue for me and I can't get it right from the first time.
In my current project, I am trying to add a comment section to item detail view.
I am currently getting an error of get_context_data() got an unexpected keyword argument 'object'
which is from the item detail view as I indicated and I don't know who to fix it
Here is the item model:
class Item(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
here is the comment model:
class Comment(models.Model):
STATUS = (
('New', 'New'),
('True', 'True'),
('False', 'False'),
)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="ItemComments")
subject = models.CharField(max_length=50, blank=True)
comment = models.CharField(max_length=250, blank=True)
status = models.CharField(max_length=10, choices=STATUS, default='New')
create_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '{} by {}'.format(self.subject, str(self.user.username))
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ['subject', 'comment']
here is the view:
class ItemDetailView(DetailView):
model = Item
template_name = "product.html"
def get_context_data(request, id):
context = super(ItemDetailView, request).get_context_data() <---------------- error from this line
context["comments"] = Comment.objects.filter(item_id=id, status='True')
return context
here is the add coment view
def addcomment(request,id):
url = request.META.get('HTTP_REFERER') # get last url
# return HttpResponse(url)
if request.method == 'POST': # check post
form = CommentForm(request.POST)
if form.is_valid():
data = Comment() # create relation with model
data.subject = form.cleaned_data['subject']
data.comment = form.cleaned_data['comment']
data.item_id = id
current_user = request.user
data.user_id = current_user.id
data.save() # save data to table
messages.success(request, "Your review has ben sent. Thank you for your interest.")
return HttpResponseRedirect(url)
return HttpResponseRedirect(url)
Here is the traceback
Traceback (most recent call last):
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\views\generic\detail.py", line 107, in get
context = self.get_context_data(object=self.object)
File "C:\Users\Ahmed\Desktop\Project 4.3\core\views.py", line 113, in get_context_data
context["comments"] = Comment.objects.filter(item_id=id, status='True')
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\query.py", line 892, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\query.py", line 910, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\sql\query.py", line 1290, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\sql\query.py", line 1315, in _add_q
child_clause, needed_inner = self.build_filter(
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\sql\query.py", line 1251, in build_filter
condition = self.build_lookup(lookups, col, value)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\sql\query.py", line 1116, in build_lookup
lookup = lookup_class(lhs, rhs)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\lookups.py", line 20, in __init__
self.rhs = self.get_prep_lookup()
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\fields\related_lookups.py", line 115, in get_prep_lookup
self.rhs = target_field.get_prep_value(self.rhs)
File "C:\Users\Ahmed\Desktop\Project 4.3\venv\lib\site-packages\django\db\models\fields\__init__.py", line 966, in get_prep_value
return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'builtin_function_or_method'
The signature of get_context_data(...) method is wrong in your view. It should be as follows,
class ItemDetailView(DetailView):
model = Item
template_name = "product.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["comments"] = Comment.objects.filter(item=self.object, status='True')
return context
I am using Django Rest Framework. I have an existing database (cannot make any changes to it). I have composite pk on my table TestSuite. When I do a get() on the test_suites it throws an error - 'str' object has no attribute 'pk' . I haven't defined pk in my model, as with django I cannot define composite primary keys. Hence, django uses 'id' an autogenerated pk for the model. I cannot add id in my database (as I cannot modify the db).
The post() works as expected, however get() is throwing error through postman() as well as browsable API.
I am new to DRF. Any help is appreciated.
DB create statement:
CREATE TABLE `test_suite` (
`team_name` varchar(30) NOT NULL,
`suite_name` varchar(100) NOT NULL,
`description` varchar(200) DEFAULT NULL,
`schedule` varchar(100) DEFAULT NULL,
`email_list_ok` varchar(200) DEFAULT NULL,
`email_list_fail` varchar(200) DEFAULT NULL,
`template_name` varchar(100) NOT NULL,
PRIMARY KEY (`team_name`,`suite_name`),
KEY `fk_test_suite__email_templates` (`template_name`),
CONSTRAINT `fk_test_suite__email_templates` FOREIGN KEY (`template_name`) REFERENCES `email_templates` (`template_name`),
CONSTRAINT `fk_test_suite__team` FOREIGN KEY (`team_name`) REFERENCES `team` (`team_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I need to do a get() and post() to this table. Below are my models , serializers and viewsets.
models.py
class Team(models.Model):
team_name = models.CharField(primary_key=True, max_length=30)
description = models.CharField(max_length=100, blank=True, null=True)
class Meta:
managed = False
db_table = 'team'
class TestSuite(models.Model):
team_name = models.ForeignKey(Team, on_delete=models.DO_NOTHING, db_column='team_name')
suite_name = models.CharField(max_length=100)
description = models.CharField(max_length=200, blank=True, null=True)
schedule = models.CharField(max_length=100, blank=True, null=True)
email_list_ok = models.CharField(max_length=200, blank=True, null=True)
email_list_fail = models.CharField(max_length=200, blank=True, null=True)
template_name = models.ForeignKey(EmailTemplates, on_delete=models.DO_NOTHING, db_column='template_name')
class Meta:
managed = False
db_table = 'test_suite'
unique_together = (('team_name', 'suite_name'),)
views.py
class TestSuiteViewSet(viewsets.ModelViewSet):
queryset = models.TestSuite.objects.values('team_name','suite_name', 'description','schedule','email_list_ok','email_list_fail','template_name')
serializer_class = serializers.TestSuiteSerializer
class TeamViewSet(viewsets.ModelViewSet):
queryset = models.Team.objects.all()
serializer_class = serializers.TeamSerializer
serializers.py
class TestSuiteSerializer(serializers.ModelSerializer):
class Meta:
model = models.TestSuite
fields = ['team_name','suite_name', 'description','schedule','email_list_ok','email_list_fail','template_name']
Error Traceback:
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.6/contextlib.py" in inner
52. return func(*args, **kwds)
File "/usr/local/lib/python3.6/dist-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/viewsets.py" in view
116. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
495. response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in handle_exception
455. self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
492. response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/mixins.py" in list
48. return Response(serializer.data)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in data
768. ret = super(ListSerializer, self).data
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in data
262. self._data = self.to_representation(self.instance)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in to_representation
686. self.child.to_representation(item) for item in iterable
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in <listcomp>
686. self.child.to_representation(item) for item in iterable
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in to_representation
530. ret[field.field_name] = field.to_representation(attribute)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/relations.py" in to_representation
272. return value.pk
Exception Type: AttributeError at /dqf_api/test_suites/
Exception Value: 'str' object has no attribute 'pk'
urls.py
router = routers.DefaultRouter()
router.register(r'teams', views.TeamViewSet)
router.register(r'test_suites', views.TestSuiteViewSet)
urlpatterns = [ url(r'^dqf_api/', include(router.urls))]
EDIT:
I was able to resolve get()by adding below code to my serializers.py However, now my post() is not working - ValueError at /dqf_api/test_suites/
Cannot assign "'ede'": "TestSuiteModel.team_name" must be a "Team" instance.
def to_representation(self, obj):
return {
'team_name': obj.get('team_name'),
'suite_name': obj.get('suite_name'),
'description': obj.get('description'),
'schedule': obj.get('schedule'),
'email_list_ok': obj.get('email_list_ok'),
'email_list_fail': obj.get('email_list_fail'),
'template_name': obj.get('template_name'),
}
def to_internal_value(self, data):
return {
'team_name': data.get('team_name'),
'suite_name': data.get('suite_name'),
'description': data.get('description'),
'schedule': data.get('schedule'),
'email_list_ok': data.get('email_list_ok'),
'email_list_fail': data.get('email_list_fail'),
'template_name': data.get('template_name'),
}
Error Traceback:
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.6/contextlib.py" in inner
52. return func(*args, **kwds)
File "/usr/local/lib/python3.6/dist-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/viewsets.py" in view
116. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
495. response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in handle_exception
455. self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
492. response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/mixins.py" in create
21. self.perform_create(serializer)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/mixins.py" in perform_create
26. serializer.save()
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in save
214. self.instance = self.create(validated_data)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in create
943. instance = ModelClass._default_manager.create(**validated_data)
File "/usr/local/lib/python3.6/dist-packages/django/db/models/manager.py" in manager_method
82. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/django/db/models/query.py" in create
415. obj = self.model(**kwargs)
File "/usr/local/lib/python3.6/dist-packages/django/db/models/base.py" in __init__
477. _setattr(self, field.name, rel_obj)
File "/usr/local/lib/python3.6/dist-packages/django/db/models/fields/related_descriptors.py" in __set__
197. self.field.remote_field.model._meta.object_name,
Exception Type: ValueError at /dqf_api/test_suites/
Exception Value: Cannot assign "'ede'": "TestSuiteModel.team_name" must be a "Team" instance.
There was issue with serialization and deserialization with foreign key relations. I fixed it by adding below code to the serializers.py
class TestSuiteSerializer(serializers.ModelSerializer):
class Meta:
model = models.TestSuiteModel
fields = ['team_name','suite_name', 'description','schedule','email_list_ok','email_list_fail','template_name']
def to_representation(self, obj):
if isinstance(obj, dict): # get methods
return obj
else:
self.fields['team_name'] = TeamSerializer()
self.fields['template_name'] = EmailTemplatesSerializer()
return super(TestSuiteSerializer, self).to_representation(obj)
I've read a bunch of similar sounding questions of SO, but somehow none of them have helped me solve my particular case. I added a ManyToManyField to represent "Likes" to my Photo model:
class Photo(TimestampModerated):
owner = models.ForeignKey('auth.User', related_name='photos', on_delete=models.CASCADE)
uuid = models.UUIDField(default=uuid4, editable=False)
slug = models.SlugField(max_length=80, editable=False)
title = models.CharField(max_length=80, blank=False, null=False)
description = models.TextField(verbose_name='description of entity', blank=True, null=True)
photo = models.ImageField(upload_to=user_directory_path, height_field="height", width_field="width", blank=True)
height = models.IntegerField(blank=True)
width = models.IntegerField(blank=True)
tags = TaggableManager(blank=True)
hash = models.CharField(max_length=64, unique=True, null=True)
size = models.BigIntegerField('size of file in bytes', blank=True, null=True)
likes = models.ManyToManyField('auth.User', blank=True, null=True)
class Meta:
verbose_name_plural = "photos"
def __str__(self):
return self.title
def delete(self, using=None, keep_parents=False):
default_storage.delete("{}".format(self.photo))
super().delete()
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Photo, self).save(*args, **kwargs)
Here is the view (at least the part that should matter for creating):
class PhotoViewSet(viewsets.ModelViewSet):
queryset = Photo.objects.all()
serializer_class = PhotoSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsOwnerOrReadOnly, permissions.AllowAny,)
parser_classes = (MultiPartParser, FormParser)
def perform_create(self, serializer):
serializer.save(owner=self.request.user, likes=[])
And here is the serializer:
class PhotoSerializer(serializers.ModelSerializer, TaggitSerializer):
owner = serializers.CharField(source='owner.username', read_only=True)
tags = TagListSerializerField()
photo = Base64ImageField(
max_length=None, use_url=True,
)
class Meta:
model = Photo
fields = ('photo', 'height', 'width', 'owner', 'slug', 'uuid', 'title', 'id', 'created', 'updated',
'moderation_code', 'tags', 'hash', 'description', 'size', 'likes')
def create(self, validated_data):
photo = Photo.objects.create(owner=validated_data.pop('owner'),
**validated_data)
p = Photo.objects.get(uuid=photo.uuid)
[p.tags.add(tag) for tag in validated_data['tags']]
return photo
To be clear, the only thing that has been added is the likes field in the model. Also, I should note that I am able to actually POST new likes to photos that already existed in the DB before the migration. I'm just having issues creating new instances. Any ideas?
Here is the full error traceback:
Internal Server Error: /api/photos/
Traceback (most recent call last):
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/viewsets.py", line 86, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/views.py", line 489, in dispatch
response = self.handle_exception(exc)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/views.py", line 449, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/views.py", line 486, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/mixins.py", line 21, in create
self.perform_create(serializer)
File "/Users/xxxxxx/_/photos/views.py", line 24, in perform_create
serializer.save(owner=self.request.user, likes=[])
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 215, in save
self.instance = self.create(validated_data)
File "/Users/xxxxxx/_/photos/serializers.py", line 88, in create
**validated_data)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/query.py", line 392, in create
obj = self.model(**kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/base.py", line 566, in __init__
_setattr(self, prop, kwargs[prop])
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 536, in __set__
manager = self.__get__(instance)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 513, in __get__
return self.related_manager_cls(instance)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 830, in __init__
(instance, self.pk_field_names[self.source_field_name]))
ValueError: "<Photo: photo-260561.jpeg>" needs to have a value for field "id" before this many-to-many relationship can be used.
Well, I solved this with one seemingly very simple line of code:
def create(self, validated_data):
validated_data.pop('likes') ## adding this line solved the issue
photo = Photo.objects.create(owner=validated_data.pop('owner'),
**validated_data)
p = Photo.objects.get(uuid=photo.uuid)
[p.tags.add(tag) for tag in validated_data['tags']]
return photo
If anyone can explain why this works, I'd be interested to know. I should point out that for this use case a photo would never be initiated with likes.
In django rest framework If i use DictField() in serializer its given me AttributeError at /api/v1/analytics/reports-configuration/1/
‘str’ object has no attribute ‘items’ error.please take a look.
serializers.py
import json
from rest_framework import serializers
from models import ReportConfiguration
class ReportConfigurationSerializer(serializers.ModelSerializer):
report_type = serializers.ChoiceField(choices=['query', 'activity', 'summary'])
read_only = serializers.BooleanField(required=True)
query_data = serializers.DictField(required=True)
class Meta:
model = ReportConfiguration
fields = ('id', 'title', 'query_data', 'created_by', 'last_activity_by', 'deleted',
'deleted_by', 'added_at', 'last_activity_at', 'report_type', 'read_only')
def validate(self, data):
if data['report_type'] is not 'summary' and data['read_only'] is True:
raise serializers.ValidationError("If read only true then report type should be summary")
if data['report_type'] is 'summary' and data['read_only'] is not True:
raise serializers.ValidationError("If read only not true then report type should not be summary")
return data
def create(self, validated_data):
validated_data['created_by'] = self.context['request'].user
validated_data['last_activity_by'] = self.context['request'].user
return ReportConfiguration.objects.create(**validated_data)
views.py
class ReportConfigurationViewSet(viewsets.ModelViewSet):
serializer_class = ReportConfigurationSerializer
queryset = ReportConfiguration.objects.all()
permission_classes = (permissions.IsAuthenticated,)
filter_backends = (DjangoFilterBackend,)
filter_class = ReportFilter
def list(self, request):
response = super(ReportConfigurationViewSet, self).list(request)
for data in response.data['results']:
data['query_data'] = json.loads(data['query_data'])
return response
def retrieve(self, request, pk=None):
response = super(ReportConfigurationViewSet, self).retrieve(request, pk=pk)
response.data['query_data'] = json.loads(response.data['query_data'])
return response
models.py
class ReportConfiguration(models.Model):
class ReportTypeChoice(Choice):
QueryReport = 'query'
ActivityReport = 'activity'
SummaryList = 'summary'
title = models.CharField(max_length=300, unique=True, blank=False, null=False)
query_data = JSONField(default={})
created_by = models.ForeignKey(User, null=True, blank=True, related_name='report_created_by')
last_activity_by = models.ForeignKey(User, null=True, blank=True,related_name='last_active_in_report')
deleted = models.BooleanField(default=False)
deleted_by = models.ForeignKey(User, null=True, blank=True, related_name='report_deleted_by')
added_at = models.DateTimeField(auto_now_add=True)
last_activity_at = models.DateTimeField(default=timezone.now)
report_type = models.CharField(max_length=15, choices=ReportTypeChoice)
read_only = models.BooleanField(default=False)
Error:
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
ERROR Internal Server Error: /api/v1/analytics/reports-configuration/1/
Traceback (most recent call last):
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/viewsets.py", line 83, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/views.py", line 477, in dispatch
response = self.handle_exception(exc)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/views.py", line 437, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/views.py", line 474, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/ranvijay.s/wk/project/django/dhanalytics/views.py", line 47, in retrieve
response = super(ReportConfigurationViewSet, self).retrieve(request, pk=pk)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/mixins.py", line 58, in retrieve
return Response(serializer.data)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/serializers.py", line 527, in data
ret = super(Serializer, self).data
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/serializers.py", line 262, in data
self._data = self.to_representation(self.instance)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/serializers.py", line 496, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/fields.py", line 1601, in to_representation
for key, val in value.items()
AttributeError: 'str' object has no attribute 'items'
I have a problem with validation of form containing ModelMultipleChoiceField.
In face on submit, I have this error :
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/Proapp/main_app/views.py", line 275, in felicitationInscription
if completerProfilForm.is_valid() :
File "/usr/local/lib/python2.7/dist-packages/django/forms/forms.py", line 161, in is_valid
return self.is_bound and not self.errors
File "/usr/local/lib/python2.7/dist-packages/django/forms/forms.py", line 153, in errors
self.full_clean()
File "/usr/local/lib/python2.7/dist-packages/django/forms/forms.py", line 362, in full_clean
self._clean_fields()
File "/usr/local/lib/python2.7/dist-packages/django/forms/forms.py", line 380, in _clean_fields
value = field.clean(value)
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 1254, in clean
qs = self._check_values(value)
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 1287, in _check_values
pks = set(force_text(getattr(o, key)) for o in qs)
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 1287, in <genexpr>
pks = set(force_text(getattr(o, key)) for o in qs)
AttributeError: 'unicode' object has no attribute 'pk'
So my form is like this :
class inscritForm(forms.ModelForm) :
firstname = forms.CharField(max_length=50,widget=forms.TextInput(attrs={'class':'form-control'}))
class Meta :
model = Inscrit
fields = ['firstname','skills']
def __init__(self, *args, **kwargs):
super(inscritForm, self).__init__(*args, **kwargs)
thedomains = Domain.objects.values_list('name',flat=True)
self.fields["skills"] = forms.ModelMultipleChoiceField(queryset=thedomains, widget=forms.CheckboxSelectMultiple()
for key, field in self.fields.iteritems():
self.fields[key].required = False
And the models :
class Inscrit(models.Model):
user = models.OneToOneField(User)
competences = models.ManyToManyField(Speciality,related_name='specialities')
class Domain(models.Model):
name = models.CharField(max_length=20,primary_key=True)
def __str__(self) :
return self.name
def __unicode__(self) :
return self.name
#python_2_unicode_compatible
class Speciality(models.Model):
domain = models.ForeignKey(Domain,null=False)
specificity = models.TextField(max_length=100,null=True)
def __str__(self):
return u'%s %s'%(self.domain.name, self.specificity)
And finally my validation in the view :
...
if request.method == "POST" :
form = inscritForm(request.POST)
if form.is_valid() : # Errors here
...
I tested if instances of Domain have attribute 'pk' in the shell and YES they have...
Since are using a model multiple choice field, you should use a regular queryset instead of values().
thedomains = Domain.objects.all()
self.fields["skills"] = forms.ModelMultipleChoiceField(queryset=thedomains, widget=forms.CheckboxSelectMultiple())