2016-04-16 17 views
0

Ich arbeite an meiner ersten Django-App. Ich baue eine App, mit der der Nutzer Bier bewerten kann. Ich möchte, dass mein Benutzer einen Eintrag bearbeiten kann, den er bereits erstellt hat. Ich nehme sie zu einem ModelForm und frage nach ihrem Eintrag. Wenn die POST-Methode aufgerufen wird, sind meine Daten ungültig. Hier ist meine model.py:Bearbeiten Sie Modelldaten mit ModelForm: ModelForm Validierungsfehler

from django.db import models 


class Rating(models.Model): 
    beer_name = models.TextField() 
    score = models.DecimalField(max_digits=2, decimal_places=1) 
    notes = models.TextField(blank=True) 
    brewer = models.TextField(blank=True) 

und forms.py:

from django import forms 
from ratings.models import Rating 


class RatingForm(forms.ModelForm): 
    class Meta: 
     model = Rating 
     fields = ['beer_name', 'score', 'notes', 'brewer'] 

Hier ist die views.py meiner Editierfunktion:

def edit(request, row_id): 
    rating = get_object_or_404(Rating, pk=row_id) 
    if request.method == "POST": 
     form = RatingForm(request.POST, instance=rating) 
     if form.is_valid(): 
      form.save() 
      return redirect(home) 
     else: 
      return HttpResponse("Invalid entry.") 
    else: 
     context = {'form': rating} 
     form = RatingForm(instance=rating) 
     return render(
      request, 
      'ratings/entry_def.html', 
      context 
     ) 

jedoch jedes Mal, wenn der POST heißt ich bekomme einen "ungültigen Eintrag". HttpResponse, was bedeutet, dass meine form.is_valid() False zurückgegeben wird. Hier ist meine Vorlage:

{% extends "base.html" %} 

{% block content %} 
    <div class="container-fluid"> 
    <div class="row"> 
     <div class="col-sm-10 col-sm-offset-1"> 
     <h2>Edit Rating</h2> 
     <form role="form" method="post"> 
      {% csrf_token %} 
      <p>Beer Name: <textarea>{{ form.beer_name }}</textarea></p> 
      <p>Score: <input type="text" name="BeerScore" value="{{ form.score }}"></p> 
      <p>Notes: <textarea>{{ form.notes }}</textarea></p> 
      <p>Brewer: <textarea>{{ form.brewer }}</textarea></p> 
      <p><button type="submit" class="save btn btn-primary">Save</button></p> 
      <p><button type="reset" class="btn btn-primary">Cancel</button></p> 
     </form> 
     </div> 
    </div> 
    </div> 
{% endblock %} 

Also, wenn ich meine Save-Taste drücke, bekomme ich die Antwort. Hier ist meine bearbeiten url in urls.py:

urlpatterns = [ 
    ... 
    url(r'rating/edit/(?P<row_id>[0-9]+)/$', edit , name='rating-edit'), 
] 

Antwort

0

Sie Einwickeln Felder in anderen Bereichen, die keine name Attribute. Dies führt höchstwahrscheinlich dazu, dass die Werte aus den Daten request.POST ausgeschlossen werden.

Darüber hinaus haben alle Django-Formularfelder ein entsprechendes HTML-Widget. Es besteht also keine Notwendigkeit, den HTML-Code manuell zu rendern, es sei denn, Sie müssen dies tun.

auf Ihre Template-Code ändern:

<p> 
    {{ form.beer_name.label }}: {{ form.beer_name }} 
    {% if form.beer_name.errors %} 
    <br />{{ form.beer_name.errors }} 
    {% endif %}{# repeat for other fields as needed #} 
</p> 
<p>{{ form.score.label }}: {{ form.score }}</p> 

<p>{{ form.notes.label }}: {{ form.notes }}</p> 
<p>{{ form.brewer.label }}: {{ form.brewer }}</p> 
<p><button type="submit" class="save btn btn-primary">Save</button></p> 
<p><button type="reset" class="btn btn-primary">Cancel</button></p> 

Wenn Sie das Widget ändern müssen, tun dies auf dem Formular Klassenstufe:

class RatingForm(forms.ModelForm): 
    class Meta: 
     model = Rating 

    def __init__(self, *args, **kwargs): 
     super(RatingForm, self).__init__(*args, **kwargs) 

     self.fields['notes'].widget = forms.Textarea() 

Auf diese Weise gelingt es Django die Attribute und verbindlich für Sie.

Ihre Ansicht kann auch eine gewisse Bereinigung verwenden:

def edit(request, row_id): 
    rating = get_object_or_404(Rating, pk=row_id) 
    form = RatingForm(request.POST or None, instance=rating) 

    if request.method == "POST" and form.is_valid(): 
     form.save() 
     return redirect(home) 

    context = {'form': rating} 
    return render(request, 'ratings/entry_def.html', context) 
+0

Awesome! Jedes Mal, wenn ich versuchte, das HTML-Tag