I am getting an error when I try to update a record in Django using a form. I get an error that a record with that number already exists. Below is my model and view. This is really driving me nuts. I though that Django would just update the record instead of trying to write a new record.
class Report(models.Model):
report_number = models.CharField(max_length=4, unique=True)
detected = models.CharField(max_length=40)
computer_name = models.CharField(max_length=40)
username = models.CharField(max_length=15)
cab_date_time = models.CharField(max_length=40)
collector = models.CharField(max_length=40)
addresses = models.TextField()
fault = models.CharField(max_length=40)
known_malware = models.TextField(default='No')
collected_files = models.TextField(default='None')
registry_keys = models.TextField()
service_number = models.CharField(max_length=15, blank=True)
notes = models.TextField(blank=True)
sample_requested = models.CharField(max_length=4, blank=True)
action = models.CharField(max_length=35, blank=True)
And View
def reports(request, report_number):
instance = get_object_or_404(Report, report_number=report_number)
form = ReportForm(request.POST or None, instance=instance)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
return render(request, 'reports/report.html', {'form': form})
Here is the Form defination
from django.forms import ModelForm
from reports.models import Report
class ReportForm(ModelForm):
class Meta:
model = Report
exclude = ('moderator',)
def reports(request, report_number):
instance = get_object_or_404(Report, report_number=report_number)
if request.method == 'POST':
form = ReportForm(request.POST, instance=instance)
if form.is_valid():
form.save(force_update=True)
return HttpResponseRedirect('/')
else:
form = ReportForm(instance=instance)
return render(request, 'reports/report.html', {'form': form})
Related
I am currently trying to create a form where users get to fill in their details after creating an account. The idea is that every user, after registration, gets redirected to this form page to fill it out. To achieve this, i'm using foreign keys.However it doesn't save to database.
models.py
class User(AbstractUser):
pass
def __str__(self):
return self.username
class Detail(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, default="")
first_name = models.CharField(max_length=200, default="")
last_name = models.CharField(max_length=255, default="")
class Meta:
verbose_name_plural = "Detail"
def __str__(self):
return self.first_name+ " "+self.last_name
forms.py
class Details(forms.ModelForm):
class Meta:
model = Detail
fields = "__all__"
widgets={
"user": forms.TextInput()
}
views.py
def details(request):
if request.method =="POST":
form = Details(request.POST)
if form.is_valid():
detail = form.save(commit=False)
detail.user = request.user
detail.first_name = detail.first_name.lower()
detail.last_name = detail.last_name.lower()
detail.save()
return redirect("admin:index")
else:
form = Details(initial={"user":request.user.username})
return render(request, "details.html", {"form":form})
You need to exclue user field from ModelForm like this
form.py
class Details(forms.ModelForm):
class Meta:
model = Detail
fields = "__all__"
exclude =["user"]
views.py
def details(request):
if request.method =="POST":
form = Details(request.POST)
if form.is_valid():
detail = form.save(commit=False)
detail.user = request.user
detail.first_name = detail.first_name.lower()
detail.last_name = detail.last_name.lower()
detail.save()
return redirect("admin:index")
else:
form = Details()
return render(request, "details.html", {"form":form})
I tried to make a creation form for vacancy on my job search site, but i faced with problem. I have User model, company model and vacancy model. They are inherited by foreignkeys. And the problem is that user can use all companies for creation a vacancy instead of created by this user companies(User can create several companies). I tried to change creation form and view by filtering, but it didn't work out for me. I am new at django and i dint find anything to resolve my problem.
Model of company:
class Company(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(('Title of Shop'), blank=True, max_length=255)
info = models.TextField(('Information about Shop'), null=True, blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.title)
Model of vacancy:
class Vacancies(models.Model):
title = models.CharField(('Title of Vacancy'), blank=True, max_length=255)
city = models.ForeignKey(City, on_delete=models.CASCADE, default='363')
description = models.TextField(('Information about Vacancy'), null=True, blank=True)
employer = models.ForeignKey(Company, on_delete=models.CASCADE)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-updated', '-created']
def __str__(self):
return str(self.title)
Create vacancy view:
#login_required(login_url='login')
def createVacancy(request):
form = VacanciesForm()
cities = City.objects.all()
if request.method == 'POST':
form = VacanciesForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
context = {'form': form, 'cities': cities}
return render(request, 'vacancy_form.html', context)
Vacancy form:
class VacanciesForm(ModelForm):
class Meta:
model = Vacancies
fields = '__all__'
What do I need to change to get the correct display of companies in the vacancy
Try this:
#login_required(login_url='login')
def create_vacancy(request):
user = request.user
cities = City.objects.all()
if request.method == 'POST':
form = VacanciesForm(data=request.POST, instance=user)
if form.is_valid():
form.save()
return redirect('home')
context = {'form': form, 'cities': cities}
return render(request, 'vacancy_form.html', context)
Also you can use in view:
def create_vacancy(request, logined_user_id):
vacancies = Vacancies.objects.filter(owner=logined_user_id)
...
And you can try some logic here:
class VacanciesForm(ModelForm):
vacancies = [some_logic]
class Meta:
model = Vacancies
fields = '__all__'
Finally, you can read docs:
modelforms
This work:
views
def createVacancy(request):
cities = City.objects.all()
form = VacanciesForm(data=request.POST, request=request)
if form.is_valid():
form.save()
return redirect('home')
context = {'form': form, 'cities': cities,}
return render(request, 'vacancy_form.html', context)
forms
class VacanciesForm(ModelForm, forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(VacanciesForm, self).__init__(*args, **kwargs)
self.fields['employer'].queryset = EmployerCard.objects.filter(owner=self.request.user)
class Meta:
model = Vacancies
fields = '__all__'
I'm new to django and my task is to make user able to create a lot profiles after registration when he's logged in.
This is my models.py:
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(blank=False, max_length=100)
lastname = models.CharField( blank=False, max_length=100)
city = models.CharField( blank=True, max_length=100)
country = models.CharField( blank=True, max_length=100)
phonenumber = models.CharField(blank=False, null=True, max_length=20)
email = models.EmailField(blank=False, max_length=100)
date_of_birth = models.DateField( blank=True, null=True)
date_of_addition = models.DateField(auto_now=True, editable=False, null=True)
When I create my user, do login and press create profile button I get :
django.db.utils.IntegrityError: (1048, "Column 'user_id' cannot be null")
This is my views.py:
#login_required
def profile_create(request):
data = dict()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
form.save()
data['form_is_valid'] = True
profiles = Profile.objects.all()
data['html_profile_list'] = render_to_string('basic_app/users_list_1_10.html', {'profiles': profiles})
else:
data['form_is_valid'] = False
else:
form = ProfileForm()
context = {'form': form}
data['html_form'] = render_to_string('basic_app/partial_profile_create.html', context, request=request)
return JsonResponse(data)
def register(request):
registered = False
if request.method == "POST":
user_form = UserForm(data=request.POST)
if user_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
registered = True
else:
print(user_form.errors)
else:
user_form = UserForm()
return render(request,'basic_app/registration.html',{'user_form':user_form,'registered':registered})
This is my forms.py:
from django import forms
from django.forms import ModelForm
from django.contrib.auth.models import User
from .models import Profile
class ProfileForm(ModelForm):
class Meta:
model = Profile
fields = ('name', 'lastname', 'city', 'country', 'phonenumber', 'email', 'date_of_birth')
class UserForm(ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
username = forms.CharField(help_text=False)
class Meta():
model = User
fields = ('username','password')
Thanks
It happens because in your Profile model you have user field which is ForeignKey. In Django ForeignKey is required by default, which means that you can't create new Profile without specifying user field. But you don't provide user in ProfileForm.
You can either provide user in ProfileForm or set user field as not required by adding:
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
I should request user before saving ProfileForm:
#login_required
def profile_create(request):
data = dict()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
add = form.save(commit=False)
add.user = request.user
add.save()
data['form_is_valid'] = True
profiles = Profile.objects.all()
data['html_profile_list'] = render_to_string('basic_app/users_list_1_10.html', {'profiles': profiles})
else:
data['form_is_valid'] = False
else:
form = ProfileForm()
context = {'form': form}
data['html_form'] = render_to_string('basic_app/partial_profile_create.html', context, request=request)
return JsonResponse(data)
I couldn't find any solution in previous answers so i'm here asking how to register the result of a form field made by a queryset. Maybe i'm doing wrong something simple here how ever my model are:
#python_2_unicode_compatible
class Choice(models.Model):
choice_text = models.CharField(max_length=100)
def __str__(self):
return self.choice_text
#python_2_unicode_compatible
class Contatto(models.Model):
contatto_choice = models.ForeignKey(Choice, on_delete=models.PROTECT)
phone_number = models.CharField(max_length=12)
email = models.CharField(max_length=100)
text = models.CharField(max_length=250)
def __str__(self):
return self.email
class ContactForm(ModelForm):
class Meta:
model = Contatto
fields = ['contatto_choice', 'phone_number','email','text']
My forms.py is:
class ContactForm(forms.Form):
contatto_choice = forms.ModelChoiceField(queryset=Choice.objects.all())
phone_number = forms.CharField(max_length=12)
email = forms.CharField(max_length=100)
text = forms.CharField(widget=forms.Textarea, max_length=500)
and my views is:
def contatti(request):
if request.method=="POST":
form = ContactForm(request.POST)
if form.is_valid():
contatto = Contatto()
contatto.phone_number = form.cleaned_data['phone_number']
contatto.email = form.cleaned_data['email']
contatto.text = form.cleaned_data['text']
contatto.contatto_choice = form.cleaned_data['contatto_choice']
contatto.save()
recipients = ['cercaservizi#gmail.com']
send_mail("Contatto Cercaservizi", contatto.phone_number+' '+contatto.email+' '+contatto.text,contatto.email, recipients)
return HttpResponseRedirect('/')
else:
form = ContactForm()
return render(request, 'form.html', {'form': form})
The view of the submitted form complains about the fact that a contatto_choice should be an instance of a choice i cannot find any tutorial about how to solve this. If you could help it would be appreciated.
Edit Your ContactForm
class ContactForm(ModelForm):
contatto_choice = forms.ModelChoiceField(queryset=Choice.objects.all())
class Meta:
model = Contatto
fields = ['contatto_choice', 'phone_number','email','text']
and you will not need other form
i create simple page where i can add article (title, text and category). When i do it on 'site administration everything is ok', but when i add it on page i can't choose category.
http://i.stack.imgur.com/4Nxzb.jpg
I choose category, for example like on this screen but my article do not have this category after i save it (article is uncategorized).
I created forms.py file and i done it like this:
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text', 'categories')
How must i change 'categories' here to make it usable?
models.py:
from django.db import models
from django.utils import timezone
class Category(models.Model):
name = models.CharField('Nazwa Kategorii', max_length=100)
slug = models.SlugField('Odnośnik', max_length=100)
icon = models.ImageField('Ikonka Kategorii', upload_to='icons',
blank=True)
class Meta:
verbose_name = "Kategoria"
verbose_name_plural = "Kategorie"
def __unicode__(self):
return self.name
class Post(models.Model):
author = models.CharField(max_length=25, blank=True, null=True)
title = models.CharField(max_length=200)
slug = models.SlugField('Odnośnik', max_length=255)
text = models.TextField()
published_date = models.DateTimeField(
default=timezone.now)
categories = models.ManyToManyField(Category, verbose_name='Kategorie')
def publish(self):
self.published_date = timezone.now()
self.save()
def __unicode__(self):
return self.title
And from views.py my view
def post_new(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('blog.views.post_detail', pk=post.pk)
else:
form = PostForm()
return render(request, 'blog/post_edit.html', {'form': form})
When you save a form using commit=False you should call the save_m2m() method of the form:
post = form.save(commit=False)
post.author = request.user
post.save()
form.save_m2m()
Another, more elegant, solution is to pass the instance with preset field to the form's constructor. Is this case you don't need to use the commit=False argument:
form = PostForm(request.POST, instance=Post(author=request.user))
if form.is_valid():
post = form.save()
return redirect('blog.views.post_detail', pk=post.pk)