I have 2 class from my model
class APPLICANT_DATA(models.Model):
FIRST_NAME= models.CharField(max_length=20)
LAST_NAME= models.CharField(max_length=20)
MIDDLE_NAME= models.CharField(max_length=20)
and
class Applicant_status(models.Model):
fkey = models.ForeignKey(APPLICANT_DATA)
COMMENTS = models.CharField(max_length=100, null=True)
date_of_app = models.DateTimeField(auto_now_add=True, blank=True)
how do i make my 'Applicant_status' to populate whenever a data in 'APPLICANT_DATA' is inserted?
Here is my views.py
def save_page(request):
form = application_form(request.POST)
if request.method == 'POST':
if form.is_valid():
emails = form.cleaned_data['EMAIL']
mail = EmailMessage("Your activation and application code is: asdasd, do not show this to anyone", to=[emails])
mail.send()
cde = form.save(commit=False)
applicant_status.objects.create(fk=cde.id)
cde.save()
return HttpResponseRedirect('verify')
else:
form = application_form()
return render(request, 'frontend/apply.html', {'form': form})`
EDIT: My forms.py
from django.forms import ModelForm
from django import forms
from .models import APPLICANT_DATA
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
class application_form(ModelForm):
FIRST_NAME = forms.CharField( max_length=20, label = ("First Name"),
. . .
class Meta:
model = APPLICANT_DATA
fields = ('FIRST_NAME', 'LAST_NAME', 'MIDDLE_NAME', )
error is (1048, "Column 'fkey' cannot be null")
Sorry if this was a newbie question
Use django signals to achieve this. https://docs.djangoproject.com/en/1.8/topics/signals/
Or you can manually save Applicant_Status with fk set to Application_Data you have just received in your view.
Related
Based on my django project I want to add multiple users to a group and I'm trying to do this using a form. But when I try adding choices via CheckBoxSelectMultiple() widget its not working as expected.
models.py file
from django.db import models
from members.models import User
from django.contrib.auth.models import Group
class Sprint(models.Model):
status_choice = [('Working','Working'), ('Closed','Closed')]
sprint_name = models.CharField(max_length=180)
sprint_created = models.DateTimeField(auto_now= True)
lead = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='team_lead')
sprint_members = models.ForeignKey(Group, on_delete=models.CASCADE, related_name = "member")
sprint_period = models.PositiveIntegerField()
sprint_status = models.CharField(max_length=10, choices=status_choice, default='Working')
forms.py file
from django import forms
from .models import Sprint
from members.models import User
from django.core.exceptions import ValidationError
from django.contrib.auth.models import Group
class SprintForm(forms.Form):
sprint_name = forms.CharField()
sprint_period = forms.IntegerField(label="Sprint period (in days)", min_value=7)
lead = forms.ModelChoiceField(queryset= User.objects.filter(role = 'Developer'),
label="Team Lead")
sprint_members = forms.ModelChoiceField(queryset= User.objects.filter(role =
'Developer'), widget= forms.CheckboxSelectMultiple(), label="Team members")
# class Meta:
# model = Sprint
# fields = ['sprint_name', 'lead', 'sprint_period', 'sprint_members']
def clean(self):
cleaned_data = super().clean()
lead = cleaned_data.get('lead')
team = cleaned_data.get('sprint_members')
if team and lead:
if lead in team:
raise ValidationError('Team lead cant be in team')
def save(self):
team = Group.objects.get_or_create(name=f'team{self.cleaned_data["sprint_name"]}')[0]
for team_member in self.cleaned_data['sprint_members']:
team.user_set.add(team_member)
Sprint.objects.update_or_create(
sprint_name=self.cleaned_data["sprint_name"],
lead=self.cleaned_data["lead"],
sprint_period=self.cleaned_data["sprint_period"],
_members=team
)
views.py file
class SprintCreationView(generic.FormView):
model = Sprint
template_name = 'sprint_creation.html'
form_class = SprintForm
def form_valid(self, form):
form.save()
return super().form_valid(form)
When trying to submit the form it is showing "Select a valid choice. That choice is not one of the available choices."
I'm new in Django and I'm trying to pre fill one of the fields of my form with a slug.
I'm getting the slug from another model. I'm not using ForeignKey because that shows me a list with my objects and I want to save in the form the same slug that I'm using in the url.
Maybe I'm not thinking this right. What should I do?
Thank you!
This are my models:
from django.db import models
class Thing(models.Model):
name = models.CharField(max_length=255,)
rut = models.CharField(max_length=12, blank= True)
cel = models.CharField(max_length=12, blank= True)
slug = models.SlugField(unique=True)
class Control(models.Model):
id_p = models.SlugField()
pa = models.CharField(max_length=3,)
My forms
from django.forms import ModelForm
from collection.models import Thing, Control, Medicamento
class ThingForm(ModelForm):
class Meta:
model = Thing
fields = ('name', 'rut','cel','pet',)
class ControlForm(ModelForm):
class Meta:
model = Control
exclude = ['id_p']
This is what I'm doing in the views
def add_control(request, slug):
thing = Thing.objects.get(slug=slug)
form_class = ControlForm
form_class(initial={'id_p':thing})
if request.method == 'POST':
form = form_class(request.POST)
if form.is_valid():
form.save()
return redirect('thing_detail', slug=thing.slug)
else: form = form_class()
return render(request, 'things/control.html', {
'thing': thing,
'form': form,
})
So, I figure it out!
In views.py, after " if form.is_valid():"
I put this:
prev = form.save(commit=False)
prev.id_p = thing.slug
prev.save()
In that way I put the data in the excluded field before I commit the form.
I want to create a messaging function in ma django app. User should be able to write other users a textmessage.
models.py
from django.contrib.auth.models import User
class Message(models.Model):
recipient = models.ForeignKey(User, null=True)
contentDescription = models.CharField(max_length=1000, null=True)
By default, with no forms.py entry I get a selection, which will be unuseful with many users. I want the message sender to type in the user name, or in the first step the user id (which I could resolve with ajax from the name) .
Integer
But with forms.py
recipient = forms.IntegerField( widget=forms.NumberInput , required=False,)
I get:
Cannot assign "11": "Transport.recipient" must be a "User" instance.
ChoiceField and NumberInput
with:
recipient = forms.ChoiceField( widget=forms.NumberInput, required=False,)
I get the error message "not valid"
Is it possible to write the foreignkey 'manually' at all?
Try this:
recipient = forms.ModelChoiceField(queryset=User.objects.all(), widget=forms.Select, required=False)
considering your
models.py -
from django.contrib.auth.models import User
class Message(models.Model):
recipient = models.ManytoMany(User, null=True)
contentDescription = models.TextField()
forms.py
from .models import Message
from django import forms
from django.contrib.auth.models import User
class MailForm(forms.ModelForm):
recipient = forms.Charfield()
class Meta:
model = Message
fields = ('contentDescription',)
def clean_recipient(self):
user_list = self.cleaned_data.get('recipient')
# considering you post user_list of usernames as 'username1,username2,username3'
if user_list is not None:
user_list = user_list.split(',')
user_qs = User.objects.filter(username__in=userlist)
else:
raise forms.ValidationError('Error in this field')
return user_qs
def save(self, user_qs):
self.instance.user = user_qs
return super().save()
in views.py -
from .forms import MailForm
def your_view(request):
form = MailForm(request.POST or None)
if form.is_valid():
user_qs=form.cleaned_data.get('recipient')
form.save(user_qs)
#return render here
else:
#create your context here and return render
This is not perfect but can give you an idea how to implement. With the details you gave this is the best I can do for now.
models.py:
from django.db import models
from django.contrib.auth.models import User as BaseUser
CHOICE_GENDER = ((1, 'Male'), (2, 'Female'))
class Location(models.Model):
city = models.CharField(max_length=75)
country = models.CharField(max_length=25)
def __str__(self):
return ', '.join([self.city, self.state])
class Users(BaseUser):
user = models.OneToOneField(BaseUser, on_delete=models.CASCADE)
gender = models.IntegerField(choices=CHOICE_GENDER)
birth = models.DateField()
location = models.ForeignKey(Location)
class Meta:
ordering = ('user',)
forms.py:
from django.contrib.auth.forms import UserCreationForm
from django import forms
from .models import Users, Location
class LocationForm(forms.ModelForm):
class Meta:
model = Location
fields = '__all__'
class RegistrationForm(UserCreationForm):
class Meta:
model = Users
fields = ('username', 'email', 'first_name', 'last_name', 'gender', 'birth', 'location')
views.py:
def signup(request):
if request.method == "POST":
reg_form = forms.RegistrationForm(request.POST)
loc_form = forms.LocationForm(request.POST)
if loc_form.is_valid():
reg_form.location = loc_form.save()
if reg_form.is_valid():
reg_form.save()
return redirect('./')
reg_form = forms.RegistrationForm()
loc_form = forms.LocationForm()
return render(request, 'signup.html', {'loc_form': loc_form, 'reg_form': reg_form})
I can't manage to make this work, it gives location - This field is required error. I've tried every combination in views.py, and it never passed the reg_form.is_valid() command due to that reason. Can anybody help me in this? Thanks in advance!
SOLVED: views.py new, working code:
def signup(request):
if request.method == "POST":
reg_form = forms.RegistrationForm(request.POST)
loc_form = forms.LocationForm(request.POST)
if reg_form.is_valid():
reg = reg_form.save(commit=False)
if loc_form.is_valid():
reg.location = loc_form.save()
reg.save()
return redirect('./')
reg_form = forms.RegistrationForm()
loc_form = forms.LocationForm()
return render(request, 'signup.html', {'loc_form': loc_form, 'reg_form': reg_form})
Removing location from RegistrationForm fields tuple should stop the behavior.
Since you are using a separate form for Location, you shouldn't populate location field using RegistrationForm.
I have exhausted all avenues in trying to put together a solution for this, but my current knowledge of Python and Django can only get me so far.
I'm creating a basic ticketing system and CreateView used to work until I created a Profile model and then separated the Ticket model into its own app. There were already a couple of tickets created when I refactored my code which is why I know ListView works, DeleteView works as well as DetailView. CreateView works until I hit the save button.
My views and models are below; I hope someone can please help me sort this out.
Ticket Model
from django.db import models
from django.contrib.auth.models import User
....
from qcapp.models import Profile
class Ticket(models.Model):
# Relations
user = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name="tickets", verbose_name="user")
# Attributes
title = models.CharField(max_length=250, verbose_name="Title", help_text="Enter a Ticket Title")
color = models.CharField(max_length=7,
default="#ffffff",
validators=[RegexValidator("(^#[0-9a-fA-F]{3}$)|(^#[0-9a-fA-F]{6}$)")],
verbose_name="Color",
help_text="Enter the hex color code, like #ccc or #cccccc")
description = models.TextField(max_length=1000)
created_date = models.DateTimeField(default=timezone.now, verbose_name='Created Date')
created_by = models.ForeignKey(User, related_name='created_by_user')
# Attributes
# Object Manager
objects = managers.ProjectManager()
# Meta and String
class Meta:
verbose_name = "Ticket"
verbose_name_plural = "Tickets"
ordering = ("user", "title")
unique_together = ("user", "title")
def __str__(self):
return "%s - %s" % (self.user, self.title)
def get_absolute_url(self):
return reverse('ticket_detail', args=[str(self.id)])
Ticket View (CreateView Only)
# -*- coding: utf-8 -*-
...
from django.views.generic import CreateView, UpdateView, DeleteView
...
from .models import Ticket
...
class TicketCreate(CreateView):
model = Ticket
template_name = "tickets/ticket_form.html"
fields = ['title', 'description']
def form_valid(self, form):
form.instance.created_by = self.request.user
return super(TicketCreate, self).form_valid(form)
...
Profile Model(Imported Into Ticket Model)
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from django.dispatch import receiver
from django.db.models.signals import post_save
from . import managers
class Profile(models.Model):
# Relations
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="profile", verbose_name="user")
# Attributes
interaction = models.PositiveIntegerField(default=0, verbose_name="interaction")
# Attributes
# Object Manager
objects = managers.ProfileManager()
# Custom Properties
#property
def username(self):
return self.user.username
# Methods
# Meta and String
class Meta:
verbose_name = "Profile"
verbose_name_plural = "Profiles"
ordering = ("user",)
def __str__(self):
return self.user.username
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_profile_for_new_user(sender, created, instance, **kwargs):
if created:
profile = Profile(user=instance)
profile.save()
It looks like you need to add the following to your TicketCreate class in the form_valid function:
form.instance.user = Profile.objects.get(user=self.request.user)
Let me know if that works!