2012-05-10 12 views
10

Ho cercato di creare un progetto di django che abbia utenti e quegli utenti possano aggiungere titoli di libri che hanno creato. Ma ogni volta che entro in un titolo del libro (non sulla pagina di amministrazione) ottengo questo erroreImpossibile assegnare deve essere un'istanza. Django

Cannot assign "u'Hello Wold'": "Scripter.title" must be a "Book" instance. 

models.py

from django.db import models 
from django.contrib.auth.models import User 

class Book(models.Model): 
    script_title = models.CharField(max_length=100) 

    def __unicode__(self): 
     return self.script_title 

class Scripter(models.Model): 
    user = models.OneToOneField(User) 
    name = models.CharField(max_length=30) 
    title = models.ForeignKey(Book, null=True, blank=True, default=None) 

    def __unicode__(self): 
     return self.name 

forms.py

from django import forms 
from django.contrib.auth.models import User 
from django.forms import ModelForm 
from scripters.models import Scripter#, Book 

class RegistrationForm(ModelForm): 
    username = forms.CharField(label=(u'User Name')) 
    email = forms.EmailField(label=(u'Email Address')) 
    password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False)) 
    password1 = forms.CharField(label=(u'Verify Password'), widget=forms.PasswordInput(render_value=False)) 

    class Meta: 
     model = Scripter 
     exclude = ('user','title') 

    def clean_username(self): 
     username = self.cleaned_data['username'] 
     try: 
      User.objects.get(username=username) 
     except User.DoesNotExist: 
      return username 
     raise forms.ValidationError("User Name has been taken!") 

    def clean(self): 
     if self.cleaned_data['password'] != self.cleaned_data['password1']: 
      raise forms.ValidationError("The passwords did not match") 
     else: 
      return self.cleaned_data 

class LoginForm(forms.Form): 
    username = forms.CharField(label=(u'Username')) 
    password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False)) 

class CreateScript(ModelForm): 
    title = forms.CharField(label=(u'Script Title')) 

    class Meta: 
     model = Scripter 
     exclude = ('user','name',) 

    def clean_title(self): 
     title = self.cleaned_data['title'] 
     return title 

views.py

from django.http import HttpResponseRedirect 
from django.contrib.auth.models import User 
from django.contrib.auth.decorators import login_required 
from django.shortcuts import render_to_response 
from django.template import RequestContext 
from scripters.forms import RegistrationForm, LoginForm, CreateScript 
from scripters.models import Scripter, Book 
from django.contrib.auth import authenticate, login, logout 

def ScripterRegistration(request): 
    if request.user.is_authenticated(): 
     return HttpResponseRedirect('/profile/') 
    if request.method =='POST': 
     form = RegistrationForm(request.POST) 
     if form.is_valid(): 
      user = User.objects.create_user(username=form.cleaned_data['username'], 
       email = form.cleaned_data['email'], 
       password = form.cleaned_data['password'] 
      ) 
      user.save() 
      scripter = Scripter(user=user, name=form.cleaned_data['name']) 
      scripter.save() 

      return HttpResponseRedirect('/profile/') 
     else: 
      return render_to_response('index.html', {'form': form}, context_instance=RequestContext(request)) 
    else: 
     form = RegistrationForm() 
     context = {'form': form} 
     return render_to_response('index.html', context, context_instance=RequestContext(request)) 

@login_required 
def Profile(request): 
    if not request.user.is_authenticated(): 
     return HttpResponseRedirect('/login/') 
    Scripter = request.user.get_profile() 

    context = {'Scripter': Scripter, 'Book': Book} 
    return render_to_response('profile.html', context, context_instance=RequestContext(request)) 

def LoginRequest(request): 
    if request.user.is_authenticated(): 
     return HttpResponseRedirect('/profile/') 
    if request.method == 'POST': 
     submit = LoginForm(request.POST) 
     if submit.is_valid(): 
      username = submit.cleaned_data['username'] 
      password = submit.cleaned_data['password'] 
      scripter = authenticate(username=username, password=password) 
      if scripter is not None: 
       login(request, scripter) 
       return HttpResponseRedirect('/profile/') 
      else: 
       return HttpResponseRedirect('/login/') 
    else: 
     submit = LoginForm() 
     context = {'submit': submit} 
     return render_to_response('login.html',context, context_instance=RequestContext(request)) 

def LogoutRequest(request): 
    logout(request) 
    return HttpResponseRedirect('/login/') 

@login_required 
def NewScript(request): 
    if not request.user.is_authenticated(): 
     return HttpResponseRedirect('/login/') 
    if request.method =='POST': 
     title_form = CreateScript(request.POST) 
     if title_form.is_valid(): 
      new_script = Book.objects.get_or_create(
       script_title = title_form.cleaned_data['title'] 
      ) 
      new_script.save() 
      script = Book(script_title=title_form.cleaned_data['title']) 
      script.save() 
      return HttpResponseRedirect('/edit/') 
     else: 
      return render_to_response('NewScript.html', {'title_form': title_form}, context_instance=RequestContext(request)) 
    else: 
     title_form = CreateScript() 
     context = {'title_form': title_form} 
     return render_to_response('NewScript.html', context, context_instance=RequestContext(request)) 

risposta

11

Naturalmente. Non sono sicuro di dove sia la confusione. Scripter.title è una chiave esterna a Book, quindi è necessario assegnargli uno Book effettivo, non una stringa.

5

Per prima cosa, anche se questa non è la tua domanda, credo che ti sia sfuggito qualcosa. Se ho capito bene, desideri che gli sceneggiatori abbiano MULTIPLI libri. Ora, con i tuoi modelli, possono avere solo un libro. Se sono corretti a partire da ciò che si sta cercando di ottenere, il vostro modello dovrebbe piuttosto simile a questa:

class Book(models.Model): 
    script_title = models.CharField(max_length=100) 
    scripter = models.ForeignKey(Scripter)#A book "remembers" who wrote it 

    def __unicode__(self): 
    return self.script_title 

class Scripter(models.Model): 
    user = models.OneToOneField(User) 
    name = models.CharField(max_length=30) 
    #Scripter can write multiple books, can't he? So the next line is removed, 
    #replaced by an extra line in Book class 

    # title = models.ForeignKey(Book, null=True, blank=True, default=None) 

allora si sarebbe accedere libri Scripter come questo:

scripter = Scripter.objects.get(name="joshua") 
books = scripter.book_set.all() #all books written by joshua 

Per quanto riguarda la tua domanda, in forma attuale, si avrebbe bisogno di fare qualcosa di simile:

book = Book.objects.get(script_title="some_title") 
scripter.title = book 

Ma, come ho detto prima, è necessario modificare la struttura del modello, in modo da essere piuttosto fare:

scripter = Scripter.objects.get(name="joshua") 
book = Book.objects.Create(script_title="some title",scripter=scripter) 
Problemi correlati