Altough我的表单发送报价已正确显示,我提交报价时没有错误,它们没有保存在我的数据库中。 我知道通过检查管理站点,没有保存任何对象。 但另一方面,我已经编写了注册代码,用户也保存在数据库中。
我怀疑我的两个模型之间的ForeignKey关系是罪魁祸首。
models.py
from django.db import models
class User(models.Model):
username = models.CharField(max_length=30, unique=True, blank=False)
password1 = models.CharField(max_length=40, blank=False)
password2 = models.CharField(max_length=40, blank=False)
mail = models.EmailField(unique=True, blank=False)
birthday = models.DateField(blank=False)
date = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name="Date d'inscription")
def __str__(self):
return self.username
class Offer(models.Model):
publisher = models.ForeignKey(User)
content = models.TextField()
date = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name="Date de parution")
def __str__(self):
return self.publisher.username
forms.py
from django import forms
from django.contrib import admin
from django.contrib.auth.hashers import make_password, check_password
from django.utils.translation import ugettext_lazy as _
from myuser.models import User, Offer
class UserCreationForm(forms.ModelForm):
class Meta:
model = User
widgets = {
'password1' : forms.PasswordInput(),
'password2' : forms.PasswordInput(),
}
fields = ("username", "password1", "password2", "mail")
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("les mots de passes ne correspondent pas")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserCreationForm, self).save(commit=False)
user.password1 = make_password(self.cleaned_data["password1"])
user.password2 = make_password(self.cleaned_data["password2"])
if commit:
user.save()
return user
class LoginForm(forms.Form):
username = forms.CharField(label="nom d'utilisateur")
password = forms.CharField(label="mot de passe",
widget = forms.PasswordInput)
def clean(self):
cleaned_data = super(LoginForm, self).clean()
username = cleaned_data.get('username')
password = cleaned_data.get('password')
user = User.objects.get(username=username)
if check_password(password, user.password1):
return cleaned_data
else:
raise forms.ValidationError("Le nom d'utilisateur et le mot de passe ne correspondent pas")
class SendOfferForm(forms.ModelForm):
class Meta:
model = Offer
fields = ('content',)
Views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.exceptions import ObjectDoesNotExist
from myuser.models import User, Offer
from myuser.forms import UserCreationForm, LoginForm, SendOfferForm
def get_logged_user_from_request(request):
if 'logged_user_id' in request.session:
logged_user_id = request.session['logged_user_id']
return User.objects.get(id=logged_user_id)
else:
return None
def register(request):
registered = False
if request.method == 'POST':
user_form = UserCreationForm(data=request.POST)
if user_form.is_valid():
user = user_form.save()
registered = True
else:
print(user_form.errors)
else:
user_form = UserCreationForm()
return render(request,
'myuser/create_account.html',
{'user_form': user_form, 'registered': registered} )
def login(request):
if request.method=='POST':
form = LoginForm(request.POST)
try:
if form.is_valid():
user = User.objects.get(username=request.POST.get('username'))
logged_user = User.objects.get(username=request.POST.get('username'))
request.session['logged_user_id'] = logged_user.id
return HttpResponseRedirect('/')
else:
error = "le nom d'utilisateur et le mot de passe ne correspondent pas"
return HttpResponse("Invalid login details supplied.")
except User.DoesNotExist:
return HttpResponse("Invalid login details supplied.")
else:
form = LoginForm
return render(request, 'myuser/mylogin.html', locals())
def send_offer(request):
sent = False
logged_user = get_logged_user_from_request(request)
if logged_user:
if request.method == 'POST':
try:
offerform = SendOfferForm(request.POST, instance=logged_user)
if offerform.is_valid():
sent = True
offerform.save()
else:
print(offerform.errors)
except:
return HttpResponse("drapeau except")
else:
offerform = SendOfferForm(instance=logged_user)
else:
return HttpResponse("Vous n'êtes pas connecté")
return render(request, 'myuser/send_offer.html', locals())
urls.py
from django.conf.urls import patterns, url, include
from django.views.generic import TemplateView
urlpatterns = patterns('myuser.views',
url(r'^inscription/$', 'register', name='create_account'),
url(r'^connexion/$', 'login', name='login'),
url(r'^envoyer_une_offre$', 'send_offer', name='send_offer'),
)
send_offer.html
{% extends "base.html" %}
{% block content %}
<h1> Offer </h1>
{% if not sent %}
<p> write your offer <p/>
<form action="{% url "send_offer" %}" method='POST' class='sendofferform'>
{{ form.errors }}
{{ form.non_field_errors }}
{% csrf_token %}
{{ offerform.as_p }}
<input type="submit" value="Submit" />
</form>
{% else %}
Offer is published
<a href="/poster_une_offre">publish another offer?</a><br />
<a href="/">get back to the homepage</a><br />
{% endif %}
{% endblock %}
admin.py
from django.contrib import admin
from myuser.models import User, Offer#, Message
class UserAdmin(admin.ModelAdmin):
list_display = ('id', 'username', 'status', 'college', 'apercu_description')
list_filter = ('id', 'username', 'birthday')
date_hierarchy = 'date'
ordering = ('date', )
search_fields = ('username', 'description')
def apercu_description(self, User):
text = User.description[0:40]
if len(User.description) > 40:
return '%s' % text
else:
return text
class OfferAdmin(admin.ModelAdmin):
list_display = ('id', 'publisher', 'apercu_offre')
list_filter = ('id', )
date_hierarchy = 'date'
ordering = ('date', )
search_fields = ('publisher',)
def apercu_offre(self, Offer):
text = Offer.content[0:40]
if len(Offer.content) > 40:
return '%s' % text
else:
return text
admin.site.register(User, UserAdmin)
admin.site.register(Offer, OfferAdmin)
所有其他功能工作(注册和登录)和register()功能正确保存用户,但send_offer()函数非常类似于寄存器功能不起作用,并在互联网上搜索几个小时,我仍然不知道为什么不保存优惠。
但是当我尝试在管理网站中添加优惠时,它似乎有效。
此外,我试图在python manage.py shell中保存商品:
>>> Offer.publisher = "a"
>>> Offer.content = "lalalala"
>>> Offer.save()
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/django/core/management/commands/shell.py", line 69, in handle
self.run_shell(shell=options['interface'])
File "/usr/local/lib/python3.4/dist-packages/django/core/management/commands/shell.py", line 61, in run_shell
raise ImportError
ImportError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.4/code.py", line 90, in runcode
exec(code, self.locals)
File "<console>", line 1, in <module>
TypeError: save() missing 1 required positional argument: 'self'
编辑:解决方案是添加这些行:
if offerform.is_valid():
sent = True
offer = offerform.save(commit=False)
offer.publisher = User.objects.get(id=logged_user.id)
offer.save()
请注意,logged_user是一个函数,在view.py。中描述。
答案 0 :(得分:5)
在ModelForm上,如果在实例化时没有传递任何对象,它将在指定类型的数据库中创建一个新对象。所以在这种情况下你的SendOfferForm你已经指定了Offer。如果你确实传递了一个现有的对象,那么在这种情况下,它必须是指定的类型。
您似乎正在尝试使用当前登录的用户自动填充发布商字段。为此,您需要手动将发布者字段设置为User的实例。
如果您打算让表单在数据库中创建新的商品,请执行此操作
offerform = SendOfferForm(request.POST)
如果您尝试更新当前商品,则需要将实例对象传递到表单
offerform = SendOfferForm(request.POST, instance=someOffer)
要使用commit = False手动添加表单上的用户字段调用save,这将返回一个商品对象,而不保存到DB。此时,您有机会自定义对象中的数据,然后保存。
offer = offerform.save(commit=False)
offer.publisher = request.user.id
offer.save()
所有这些都在django文档中有更详细的解释 ModelForm documentation