2017-03-05 3 views
1

J'espère que quelqu'un peut me donner un peu d'aide sur comment faire ce qui suit avec Django (excusez-moi si je n'explique pas tout correct, encore nouveau à Django et ne sais pas beaucoup de choses):Django permet à l'utilisateur de mettre à jour la valeur TextField sur le site via des formulaires?

J'ai une table de films, ces films ont une "description" Datafield, où quand ils cliquent dessus un formulaire s'ouvre avec la description actuelle du film. S'ils cliquent deux fois sur cette description, ils sont autorisés à la modifier, puis à enregistrer la valeur. J'ai fait un petit gif pour visualiser l'idée:

enter image description here

au moins des thats l'idée de base derrière cela, jusqu'à présent, j'ai réussi à faire la plupart des choses se passent, mais malheureusement pas la partie Django où les "nouvelles" données de l'utilisateur sont envoyées à la banque de données et remplacent les anciennes données de la description.

Alors, est-ce que quelqu'un pourrait m'expliquer comment je peux faire ce travail? Je sais que je devrais probablement écrire une fonction à mon views.py et ensuite créer un nouveau modèle d'URL, mais je ne peux pas comprendre exactement comment. Donc toute aide est la bienvenue! Ci-dessous mon code (j'espère avoir inclus tous les fichiers que vous les gars ont besoin):

views.py

from django.shortcuts import get_object_or_404, render 
from django.http import HttpResponseRedirect 
from django.urls import reverse 
from django.views import generic 
from django.views.generic.list import ListView 
from .models import * 

class AllMovies(generic.ListView): 
    model = Movie 
    template_name = "consilium/index.html" 
    context_object_name = "latest_movie_list" 

class MovieDetails(generic.DetailView): 
    model = Movie 
    template_name = "consilium/detail.html" 

urls.py

from django.conf.urls import url 
from . import views 
from .models import * 
from django.views.generic.list import ListView 

app_name = "consilium" 
urlpatterns = [ 
    url(r'^$', views.AllMovies.as_view(), name="index"), 
    url(r'^(?P<slug>[\w_0-9]+)/$', views.MovieDetails.as_view(), name='detail'), 
] 

models.py

from django.db import models 
from decimal import Decimal 
from django import forms 
from django.contrib import admin 

class Movie(models.Model): 
    // removed the other models for better overview 
    description = models.TextField('Movie Description') 

    def __str__(self): 
     return self.title 

index.html

{% extends "consilium/base.html" %} 

{% block body %} 
    <table class="table"> 
     <thead> 
      <tr> 
       <th></th> 
       <th colspan="2">My Movielist</th> 
       <th> 
      </tr> 
      <tr> 
       <th></th> 
       <th>TITLE</th> 
       <th>GENRE</th> 
       <th>RELEASE DATE</th> 
       <th>DIRECTOR</th> 
       <th>DESCRIPTION</th> 
       <th>RUNTIME</th> 
       <th>STATUS</th> 
       <th>IMDB</th> 
      </tr> 
     </thead> 
     <tbody> 
      {% if latest_movie_list %} 
       {% for movie in latest_movie_list %} 
       <tr> 
        <td></td> 
        <td> 
         <a href="{% url 'consilium:detail' movie.slug %}" data-toggle="popover" data-placement="left" data-content='<img class="title-image" src="{{movie.image.url}}"/>'>{{ movie.title }}</a> 
        </td> 
        <td>{{ movie.get_genre_display}}</td> 
        <td>{{ movie.date}}</td> 
        <td>{{ movie.director}}</td> 
        <td id="icn-change" data-toggle="collapse" data-target=".demo{{ forloop.counter }}"> 
        Description <i class="fa fa-caret-right"></i> 
        </td> 
        <td>{{ movie.runtime}} min</td> 
        <td>{{ movie.get_status_display}}</td> 
        <td>{{ movie.imdb}}</td> 
       </tr> 
       <tr> 
        <td></td> 
        <td class="hiddenRow" colspan="8"> 
         <div class="container collapse demo{{ forloop.counter }}"> 
          <div class="row justify-content-center"> 
           <div class="col"> 
            <form method="post" id="usrform">{% csrf_token %} 
             <textarea id="text" class ="form-control" readonly="true" onkeydown="expandtext(this)" ondblclick="this.readOnly='';">{{movie.description}}</textarea> 
            </form> 
           </div> 
          </div> 
          <div class="row justify-content-center"> 
           <div class="col align-self-start">Double Click to Edit</div> 
           <div class="col align-self-end"> 
            <input type="submit" id="set" class="pull-right"/> 
           </div> 
          </div> 
         </div> 
        </td> 
       </tr> 
       {% endfor %} 
       {% else %} 
        <tr> 
         <td>No Movies are available.</td> 
        </tr> 
      {% endif %} 
     </tbody> 
    </table> 
{% endblock %} 

script.js

// removed all other code for overview 

// replace description text with user input 
    $('#set').click(function() { 
     var test = $('#text').val(); 
     localStorage.setItem("test", test); 
    }); 

    $('#text').text(localStorage.getItem("test")); 

J'espère que je ne manque rien, merci pour tous ceux qui peuvent me aider!

+1

Vous essayez de * mise à jour * une instance de film existant. Cochez [UpdateView] (https://docs.djangoproject.com/fr/1.10/ref/class-based-views/generic-editing/#updateview) dans les documents. –

+0

Merci, je vais le lire :) –

Répondre

0

Vous l'avez compris grâce à l'aide précieuse de la communauté pythondev slack!

views.py: obtenir le champ de description de mon modèle Film

class MovieUpdateForm(forms.ModelForm): 
    class Meta: 
     model = Movie 
     fields = ['description'] 

reverse_lazy est important, de sorte que lorsque je clique sur mon bouton, il ne me rediriger vers Consilium (mon appname)/2/mise à jour et reste sur le site d'index où j'ai ma table

class MovieUpdateView(UpdateView): 
    model = Movie 
    form_class = MovieUpdateForm 
    success_url = reverse_lazy('consilium:index') 

urls.py:

url(r'^(?P<pk>[0-9]+)/update/$', views.MovieUpdateView.as_view(), name='movie_update'), 

ici, il était important de mettre cela avant mon modèle url limace j'avais dans mon urls.py, sinon il ne fonctionne pas:

url(r'^(?P<slug>[\w_0-9]+)/$', views.MovieDetails.as_view(), name='detail'), 

Ma forme dans mon html: en utilisant pk = movie.pk il saisira le film correct et donner mon textarea le nom de « description » si ma méthode sait où les données proviennent de

<form action="{% url 'consilium:movie_update' pk=movie.pk %}" method="post" id="usrform">{% csrf_token %} 
     <textarea id="text" class ="form-control" name="description" readonly="true" onkeydown="expandtext(this)" ondblclick="this.readOnly='';">{{movie.description}}</textarea> 
     <input type="submit" id="set" class="pull-right"/> 
</form> 
1

J'ai travaillé sur un projet similaire, et voici ce que j'ai fait.

from django.forms.models import model_to_dict 

@login_required 
def edit_profile(request): 
    profile, created = ClientProfile.objects.get_or_create(user_id=request.user.id) 
    if request.method == 'POST': 
     form = ProfileSubmissionForm(request.POST, instance=profile) 
     if form.is_valid(): 
      form.save() 
      return HttpResponseRedirect(reverse('jobs:list')) 
    else: 
     profile_dict = model_to_dict(profile) 
     form = ProfileSubmissionForm(profile_dict) 
     return render(request, 'jobs/profile.html', {'form': form}) 

Essentiellement, le model_to_dict rend les valeurs stockées dans la base de données sous la forme. Le instance=profile s'assure que je mets à jour le formulaire et ne crée pas un nouvel objet.

+0

Hé, tout d'abord merci pour ça! Pourriez-vous expliquer le code pour moi un peu plus détaillé? Je suis un peu nouveau sur l'ensemble du thème Python/Django et je ne sais pas encore tout :) J'ai essayé d'utiliser votre code dans mon modèle, mais ça n'a pas vraiment fonctionné, même la console n'a rien donné messages d'erreur. Aussi ne devrais-je pas ajouter quelque chose à mon urls.py et changer mon fichier javascript? –

+0

'def edit_description (demande): description, créé = Movie.objects.get_or_create (movie_id = request.movie.id) si request.method == 'POST': form = usrform (demande.POST, instance = description) si form.is_valid(): form.save() retour HttpResponseRedirect (inverse ('consilium: index')) autre: profile_dict = model_to_dict (description) form = usrform (profile_dict) retour render (demande , 'consilium/index.html', {'form': formulaire}) ' J'ai essayé de comprendre le code que vous m'avez donné un peu, est-ce l'utilisation correcte? –