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})
Related
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__'
How can I rise the error and information, if user is puting only "dummy date" without "#"?
Email model is email = models.EmailField(max_length=254) but is only preventing passsing empty field, and nothing else. Can someone advice ?
def addContact(request):
form = ContactForm
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
form.save()
return redirect('/contact')
context = {'form': form}
return render(request, 'contact/new.html', context)
Forms:
class ContactForm(ModelForm):
class Meta:
model = Contact
fields = '__all__'
Models:
class Contact(models.Model):
full_name = models.CharField(max_length=500)
relationship = models.CharField(max_length=50)
email = models.EmailField(max_length=254)
phone_number = models.CharField(max_length=20)
address = models.CharField(max_length=100)
def __str__(self):
return self.full_name
If you use EmailField then it has a built-in validator. Here is the code (https://docs.djangoproject.com/en/3.1/ref/validators/#emailvalidator)
You can use this validator to check the user input.
Here is the source code: https://docs.djangoproject.com/en/2.2/_modules/django/core/validators/#EmailValidator
here user i want user and userprofile. useing exclude. when i add userprofile error 'WSGIRequest' object has no attribute 'userprofile'
modelform
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ('categories', 'title', 'description', 'image', 'price')
exclude = ('user','userprofile')
view
#login_required
def productpost(request):
form = ProductForm()
if request.method == "POST":
form = ProductForm(request.POST, request.FILES)
if form.is_valid():
form = form.save(commit=False)
form.user = request.user
form.userprofile = request.userprofile
form.save()
return success(request)
else:
print("The Form Is Invalid")
return render(request, 'product/postproduct.html', {'form': form})
Model
class Product(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
userprofileinfo = models.ForeignKey(UserProfileInfo, on_delete=models.CASCADE)
categories = models.ForeignKey(Categories, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
description = models.TextField()
image = models.FileField()
price = models.IntegerField()
pub_date = models.DateTimeField('date published', auto_now_add=True)
def __str__(self):
return self.title
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
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)