CreateView is throwing "DoesNotExist" when instance isn't provided to form - django

I'm getting a "DoesNotExist" error with the following set up - I've been trying to debug for a while and just can't figure it out.
class Video(models.Model):
name = models.CharField(max_length=100)
type = models.CharField(max_length=100)
owner = models.ForeignKey(User, related_name='videos')
...
#Related m2m fields
....
class VideoForm(modelForm):
class Meta:
model = Video
fields = ('name', 'type')
class VideoCreate(CreateView):
template_name = 'video_form.html'
form_class = VideoForm
model = Video
When I do this and post data for 'name' and 'type' - I get a "DoesNotExist" error. It seems to work fine with an UpdateView - or when an 'instance' is passed to init the form.
This is the exact location where the error is raised:
/usr/lib/pymodules/python2.7/django/db/models/fields/related.py in get, line 301
Does anyone know what might be going on?
Thanks

Since you have not posted your full traceback, my guess is that your owner FK is not optional, and you are not specifying one in your model form.
You need to post a full traceback.

I think it has to be class VideoForm(ModelForm) instead of VideoForm(modelForm).
If you aren't going to use the foreign key in the form use exclude = ('owner')

Related

Django Rest Framework when doing a POST getting TypeError at Function.objects.create()

I have the following model
class Funcion(models.Model):
idPelicula = models.ForeignKey(Pelicula, on_delete=models.PROTECT)
idSala = models.ForeignKey(Sala, on_delete=models.PROTECT)
horaEntrada = models.TimeField(auto_now=False, auto_now_add=False)
horaSalida = models.TimeField(auto_now=False, auto_now_add=False)
fecha = models.DateField(auto_now=False)
And the next serializer
class FuncionSerializer(serializers.ModelSerializer):
pelicula = PeliculaSerializer(read_only=True)
idPelicula = serializers.PrimaryKeyRelatedField(write_only=True, queryset=Pelicula.objects.all(), source='pelicula')
sala = SalaSerializer(read_only=True)
idSala = serializers.PrimaryKeyRelatedField(write_only=True, queryset=Sala.objects.all(), source='sala')
class Meta:
model = Funcion
fields = '__all__'
When I try to post a new Funcion with the Django api root I get the following error:
TypeError at /funcion/
Got a `TypeError` when calling `Funcion.objects.create()`. This may be because you have a writable field on the serializer class that is not a valid argument to `Funcion.objects.create()`. You may need to make the field read-only, or override the FuncionSerializer.create() method to handle this correctly.
I have used this method before for other project practices and it worked correctly.
If i delete the source='pelicula' argument for the PrimaryKeyRelatedField() it post the new funcion but when I do a get to bring al the data it doesn't show the Pelicula or Sala field just the rest
I tried deleting those arguments because the error at the end shows this message TypeError: Funcion() got unexpected keyword arguments: 'pelicula', 'sala'
The create method of the model manager does not allow "unexpected" fields. Those fields are not properties or fields of that model.
Unfortunately as far as I understand the code, the field slips through the field building functions and other into the validated_data dictionary. This is probably because every read_only field is allowed as it would be filtered out anyway before reaching the validated_data, but sourceing a read_only field goes through. I do not believe this is expected, but still causes no harm since the model managers' create method raises a TypeError.
To circumvent that issue you have two main options:
The source argument of your field may only reference fields or properties that exist on your model.
Pop any fields that are not part of the model out before being passed to the create method of the model.
The last option would look something like this:
class CoolSerializer(serializers.ModelSerializer):
not_cool = serializers.CharField(max_length=42)
def create(self, validated_data):
cool_again = validated_data.pop('not_cool', None)
# Do something with cool_again that you originally intended to do.
return super().create(validated_data)

Django custom serializer how to input ID/PK

I am trying to make custom serializer work. Can't use model serializer since I will be saving data into multiple models. Here is my code:
class RushSerializer(serializers.Serializer):
keyword = serializers.IntegerField(read_only=True)
url = serializers.URLField()
def save(self):
keyword = self.validated_data['keyword']
url = self.validated_data['url']
Url1.objects.create(keyword=keyword, url=url)
And I input data like this:
nov = {'url': 'https://domain.com/'}
nov['keyword'] = id
serializer = RushSerializer(data=nov)
It returns me this error:
KeyError at /admin/keywords/kw/add/
'keyword'
Here is the model itself:
class Url1(models.Model):
keyword = models.ForeignKey(KW)
url = models.URLField()
What is wrong with my code? I tried pretty much anything from here but can't seem to make it work.
EDIT: To clarify, it works if I do it with model serializer and this:
class Meta:
model = Url1
fields = ('keyword', 'url')
So problem isn't in input 100% but in serializer itself.
If I do keyword without read_only then I get this error:
ValueError at /admin/keywords/kw/add/ Cannot assign "104":
"Url1.keyword" must be a "KW" instance.

Why did my Serializer stop recognizing a given required value?

I have the following Model and Serializer:
Model
class Location(models.Model):
company = models.ForeignKey(Company)
title = models.CharField(max_length=100)
class Meta:
ordering = ['company']
unique_together = ['company', 'title']
Serializer
class LocationSerializer(serializers.ModelSerializer):
company = serializers.StringRelatedField()
class Meta:
model = Location
When I try to create a new Location using the Serializer:
lo = LocationSerializer(data={'title': 'test', 'company': 2})
I get back the following error:
{'company': ['This field is required.']}
What gives? The only thing I'd changed recently in either the Model or the Serializer was adding the unique_together constraint to the Model. Why is the Serializer now unable to recognize the company value?
It turns out the error message is a complete red herring. What's really happening is that there's an incompatibility between the unique_together constraint in the Model and read-only fields like StringRelatedField defined in the Serializer.
Removing unique_together from the Model restored the Serializer's functionality. Alternatively, you could remove the read-only field declaration from the Serializer. Neither really seem like an appropriate solution as they require sacrificing functionality in pretty major ways.
Right now there appears to be an issue open on DRF's GitHub related to this problem but it remains to be seen if this is Working As Intendedtm or is in fact a bug.

MultiValueDictKeyError when custom ID field is missing

I get a MultiValueDictKeyError in Django 1.6 when I define a fieldset or field in my NestedStackedInline. There I have a custom ID as CharField and wanted to hide that field. But when I do that by exclude=('id',), defining fields without that or just making it readonly, I get a MultiValueDictKeyError.
Here my code:
class MaterialInline(NestedStackedInline):
fieldsets = ('name', 'amount', 'date')
#without custom id I get that error(id=models.Charfield(primary_key=True))
model = Material
extra = 1
form = autocomplete_light.modelform_factory(Material)
class ResearchAdmin(NestedModelAdmin):
inlines = [MaterialInline, ]
fields =('id','subject', 'topic')
Error:
Exception Type: MultiValueDictKeyError
Exception Value: "u'material_set-0-id'"
Exception Location: /usr/local/lib/python2.7/dist-packages/django/utils/datastructures.py in __getitem__, line 301
...
/home/administrator/src/django-nested-inlines/nested_inlines/admin.py in change_view
269. self.add_nested_inline_formsets(request, inline, formset)
/home/administrator/src/django-nested-inlines/nested_inlines/admin.py in add_nested_inline_formsets
65. for form in formset.forms:
Does anyone knows that problem?
Thanks in advance!
I had the exact same problem. Turned out that I just needed to make the field not editable in the model. Note the last argument here:
class Material(models.Model):
uuid = models.CharField(primary_key=True, max_length=128, editable=False)
Try to set a HiddenInput widget on the id field. So, define a model form for the admin:
class MaterialForm(forms.ModelForm):
id = forms.CharField(max_length=30, widget=HiddenInput, required=False)
class Meta:
model = Material
Then replace
form = autocomplete_light.modelform_factory(Material)
in MaterialInline with
form = MaterialForm
Clearly a bit more work would be required to get it working with the autocomplete.

How to save fields that are not part of form but required in Django

I have a model with a field that is required but not entered by the user and i have a hard time saving the model without errors. My model definition looks like this:
class Goal(db.Model):
author = db.UserProperty(required=True)
description = db.StringProperty(multiline=True, required=True)
active = db.BooleanProperty(default=True)
date = db.DateTimeProperty(auto_now_add=True)
class GoalForm(djangoforms.ModelForm):
class Meta:
model = Goal
exclude = ['author', 'active']
And i use django-forms in appengine to create and validate the form. When i try to save the result of this form however....
def post(self):
data = GoalForm(data=self.request.POST)
if data.is_valid():
goal = data.save(commit=False)
goal.author = users.get_current_user()
goal.put()
self.redirect('/')
I get "ValueError: The Goal could not be created (Property author is required)"
Now i would think that by having commit=False, then adding the property for Goal, and then saving the object would allow me to do this but obviously it's not working. Any ideas?
Note that save() will raise a ValueError if the data in the form doesn't validate
You can find what you need about the save() method here:
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method
Edit: Instead of goal.put(), do a goal.save()
Edit2: This should solve your problem:
goal = Goal(author='Mr') #example
data = GoalForm(data=self.request.POST, instance=goal)
I realize this is an old question, but for the sake of others searching for a similar answer, I'm posting the following:
Unless there's a reason I missed for not doing so, but I believe this is what you need:
class Goal(db.Model):
author = db.UserProperty(auto_current_user_add=True)
...
...
For reference:
Types and Property Classes:class UserProperty()
Your GoalForm should inherit from django.forms.ModelForm and be defined such that it only requires some fields:
class GoalForm(django.forms.ModelForm):
class Meta:
model = Goal
fields = ('description', 'etc')
Not sure if this is totally working in AppEngine though.
You should also save the form (still not sure about AppEngine):
data = GoalForm(data=self.request.POST)
if data.is_valid():
data.author = users.get_current_user()
data.put()