1

I want to save selected choice in model. And I want to use Select widget for choices. I have a model:

qobj = Model1.objects.all()

CHOICE = (
    (x.id, x.name) for x in qobj
)

class Model2(models.Model):
    choice_field = models.CharField("CHOICE", max_length=77, choices=CHOICE)

And I got error: "Select a valid choice. 5 is not one of the available choices." - error when try to save. I was try forms.ModelChoiceField(queryset=qobj) - No Problem, but I can't get Model.get_choice_field_display(). May be someone know solving of this problem?

ldz
  • 2,217
  • 16
  • 21
  • What do you mean by `MyModel` is "empty"? – mfitzp Apr 06 '16 at 16:39
  • As your `.html` currently stands, you're not making use of either `date` or `name` anyway, so you could just remove those lines. – DaveBensonPhillips Apr 06 '16 at 16:44
  • Empty is i not send a form and changelist is empty –  Apr 06 '16 at 16:46
  • What is the content of `preview.html` ...is that being rendered directly after the form save (not via the `preview()` view?) i.e. `return render(request, 'WebMamOffice/en/preview.html')` – mfitzp Apr 06 '16 at 16:55
  • You can wait until you have a working answer before marking an answer correct! ;) As it stands, none of our answers apparently solve your problem. – mfitzp Apr 06 '16 at 16:55
  • It doesn't look like the `preview()` view will be called at all? – mfitzp Apr 06 '16 at 16:57
  • I marked as correct for thanks for You, this is not a bad answers and You will get a more reputation. –  Apr 06 '16 at 17:03
  • Problem in other for me None with .first() not suit, as as other without object. I need object [0] or first() without difference. –  Apr 06 '16 at 17:08

5 Answers5

2

Error is here:

date = MyModel.objects.order_by('date')[0]
name = MyModel.objects.order_by('name')[0]

MyModel.objects.order_by('date') return a QuerySet, if queryset is empty, it has no index '[0]'. Try 'first()' instead [0]:

date = MyModel.objects.order_by('date').first()
name = MyModel.objects.order_by('name').first()

Case MyModel is empty, first return None Docs: https://docs.djangoproject.com/en/1.9/ref/models/querysets/#first

Anderson Lima
  • 246
  • 4
  • 8
  • I query date in form#2 after form.save() –  Apr 06 '16 at 16:53
  • 1
    Got it, inspecting your code, a see you don't redirect to preview, so try: redirect('preview') intead render(request, 'WebMamOffice/en/preview.html') https://docs.djangoproject.com/en/1.9/topics/http/shortcuts/#redirect – Anderson Lima Apr 06 '16 at 17:16
  • Unfortunatly, with redirect list index out of range. I not understand, i call form.save() before get data[0], why this error. If i have an saved object other going well i can get date[0] of just saved form. –  Apr 06 '16 at 18:04
  • You override 'save' method or is default? – Anderson Lima Apr 06 '16 at 18:13
  • default. And in my other models this construction is working well. –  Apr 06 '16 at 18:15
  • Did You had a problem with datetime field in Django. When datetime field not migrate sometimes? –  Apr 06 '16 at 18:22
  • You have checked if the object was saved in 'DB'? – Anderson Lima Apr 06 '16 at 18:24
  • When error no saved. When i change in form.html action="form1" everything is good saved without errors. –  Apr 06 '16 at 18:27
  • There is the error, when you use action="preview", you submit you form in preview, but, preview don't save nothing, preview only render WebMamOffice/en/form1.html with form, date and name. So, when you use action="form1", form is submited in form1 view, and, form1 view save the object, then you redirect to preview. And I think you need change html from preview view too, change for 'WebMamOffice/en/preview.html'. – Anderson Lima Apr 06 '16 at 18:33
  • I think next, if i not call date in form.html and date(auto_now(true)) may be this problem will be exist everytime. May be date not autoadd? –  Apr 06 '16 at 18:36
  • Anderson Thanks so much! problem solved, i change on form1 html and change views as return HttpResponseRedirect('http://www.webmamoffice.org/en/preview'). All is good. thanks. Good Luck! –  Apr 06 '16 at 18:46
  • If you date field in models has auto_now=True, you don't need to call date, because is set automatically, I still thinking, the error still in action, to execute: form01 = MyModelForm(request.POST, request.FILES) if form01.is_valid(): form01.save() You need to submit you form in form1 view, if you use preview, you are calling form = MyModelForm() date = MyModel.objects.order_by('date')[0] name = MyModel.objects.order_by('name')[0] before save object. – Anderson Lima Apr 06 '16 at 18:47
  • Great ^^, Good Luck! – Anderson Lima Apr 06 '16 at 18:50
1

The issue is caused here:

def preview(request):
    form = MyModelForm()
    date = MyModel.objects.order_by('date')[0]
    name = MyModel.objects.order_by('name')[0]

You are querying objects, sorting and taking the first item. However, if there are no items it is not possible to do this. Instead use .first(), e.g.

    date = MyModel.objects.order_by('date').first()
    name = MyModel.objects.order_by('name').first()

This will return the first item, if there is one, or None if not. See the documentation for more info. There are also some other examples in this question for alternative ways to handle this.

However, I would recommend that you do not use this approach. When you save the new object (form01.save()) this returns the newly created object. You can then access this directly for your preview. For example:

preview_model = form01.save()

Using MyModel.objects.order_by('date').first() to get the 'latest record' opens you to a race condition when another user edits another object between the .save() and the select.

I'm not sure of the purpose of name = MyModel.objects.order_by('name').first() as this is going to return a completely different object to the previous bit (the first object sorted alphabetically) - and I cannot imagine why you would want that. Try something like the following in views.py:

def form1(request):
    form = MyModelForm()
    if request.method == 'POST':
        form01 = MyModelForm(request.POST, request.FILES)
        if form01.is_valid():
           preview = form01.save()
           date = preview.date
           return render(request, 'WebMamOffice/en/preview.html', {'form': form01, 'date': date, 'name': name})
    return render(request, 'WebMamOffice/en/form1.html', {'form': form})
Community
  • 1
  • 1
mfitzp
  • 15,275
  • 7
  • 50
  • 70
  • but i query when form is saved –  Apr 06 '16 at 16:49
  • ('date')[0] is exist when i query dfate in template #2 –  Apr 06 '16 at 16:50
  • @VolodymyrKirichinets Glad you got this sorted, but see the edits - I think there is a much simpler way to do what you want. – mfitzp Apr 08 '16 at 08:15
  • This problem is solved. But now have other. I want to get values of saved form by id for next template then make some updates. And can`t choose most convenient variant. –  Apr 08 '16 at 17:46
0

your preview() view assumes at least one instance of MyModel exists: you're accessing MyModel.objects.blah[0], which only works if there is something at [0].

pfnuesel
  • 14,093
  • 14
  • 58
  • 71
dngrs
  • 269
  • 1
  • 4
  • I use date[0] after form.save() other words date[0] is exist in theory –  Apr 06 '16 at 16:56
0

The best way to use ManyToManyField:

class Model2(models.Model):
    choice_field = models.ManyToManyField(to=Model1)
-1

This problem partial solved in django can't save model choices selected values