How can i submit two forms in django - django

I have a template where i should have 2 forms and update them, I succeded to get the 2 foms in the same template, but when i make changes nothing happens !
forms.py
class OrderManageForm(forms.ModelForm):
class Meta:
model = Order
fields = ['customer', 'product', 'quantity', 'status']
class CustomerForm(forms.ModelForm):
address = forms.CharField(widget=forms.Textarea(attrs={'rows': 5}))
class Meta:
model = Customer
fields = ['full_name', 'address', 'phone', 'city', 'email'
models.py
class Customer(models.Model):
full_name = models.CharField(max_length=150)
address = models.CharField(max_length=1500, null=True)
phone = models.CharField(max_length=20)
city = models.CharField(max_length=100)
email = models.EmailField(null=True)
def __str__(self):
return self.full_name
class Order (models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE,)
quantity = models.IntegerField(default=1)
status = models.TextField(choices=ORDER_STATUS, default='Pending')
def __str__(self):
return 'Order n°: ' + str(self.id)
views.py
def update_order(request, order_id):
order = get_object_or_404(Order, id=order_id)
cust = get_object_or_404(Customer, order__id=order_id)
if request.method == 'POST':
customer = CustomerForm(request.POST)
form = OrderManageForm(request.POST)
print(request.POST)
if form.is_valid() and customer.is_valid():
order = form.save(commit=False)
customer = customer.save()
order.customer = customer
order.save()
return redirect('orders')
else:
form = OrderManageForm(instance=order)
customer = CustomerForm(instance=cust)
return render(request, 'dashboard/order_details.html', {'form': form, 'customer': customer})
I put the 2 forms in only one form tag inside my HTML template

You need to feed the instances to the forms such that the forms can update the corresponding records:
def update_order(request, order_id):
order = get_object_or_404(Order, id=order_id)
cust = order.customer
if request.method == 'POST':
customer = CustomerForm(request.POST, instance=cust)
form = OrderManageForm(request.POST, instance=order)
if form.is_valid() and customer.is_valid():
form.save()
customer.save()
return redirect('orders')
# …
You should only redirect in case the two forms are valid, otherwise you can not see the errors that appear on the form. Furthermore you shoudld remove the customer from the fields of the OrderManageForm:
class OrderManageForm(forms.ModelForm):
class Meta:
model = Order
fields = ['product', 'quantity', 'status'] ← no customer

Related

M2M relation ship : Can't save to the through model

i have a an order model which is in m2m relationship with a product model, when i create an order, and after checking my DB, i can see the order saved but not in the through model
models.py
from inventory.models import Product
from user.models import User
class Order(models.Model):
product = models.ManyToManyField(Product, through='OrderItems' )
vendeur = models.ForeignKey(User, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
class Customer(models.Model):
full_name = models.CharField(max_length=60, verbose_name='full name')
address = models.CharField(max_length=255)
phone = models.CharField(max_length=20)
city = models.CharField(max_length=30)
class OrderItems(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order,on_delete=models.CASCADE)
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True)
views.py
#login_required
def add_order(request):
if request.method == 'POST':
form = NewOrderForm(request.POST)
if form.is_valid():
order = form.save(commit=False)
order.vendeur = request.user
order.save()
return redirect('dashboard-index', )
else :
form = NewOrderForm()
return render(request, 'dashboard/add_order.html', {'form': form})
forms.py
class NewOrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ('product','quantity')
if you use save(commit=False), Calling save_m2m() is required.
because your form has a m2m field
refer to documentions
#login_required
def add_order(request):
if request.method == 'POST':
form = NewOrderForm(request.POST)
if form.is_valid():
order = form.save(commit=False)
order.vendeur = request.user
order.save()
form.save_m2m()
return redirect('dashboard-index', )
else :
form = NewOrderForm()
return render(request, 'dashboard/add_order.html', {'form': form})

Unable to limit choices of form field to a specific user

As the title states, I am unable to limit the choices of a form field based on a specific user. For example, in the choices for the enrolled field of the form all “riders” are selectable to all “users”, rather than just the “riders” that are “owned” by the user.
I’ve tried this question and answer that essentially asks the same question, as well as some other possible solutions that deal with m2m model fields, limit_choices_to, but have not been successful.
Any advise would be greatly appreciated.
models.py
class Event(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=200, null=True)
description = models.TextField(max_length=255, null=True, blank=True)
start = models.DateTimeField(null=True, blank=True)
end = models.DateTimeField(null=True, blank=True)
enrolled = models.ManyToManyField('riders.Rider',
related_name='events', blank=True)
def __str__(self):
return self.title
model.py (different app)
class Rider(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
birthdate = models.DateField(verbose_name=None, auto_now=False)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.last_name + ', ' +self.first_name
views.py
#login_required
def enroll(request, event_id):
event = Event.objects.get(id=event_id)
if request.method != 'POST':
form = EventForm(instance=event)
else:
form = EventForm(instance=event, data=request.POST)
if form.is_valid():
enroll = form.save(commit=False)
enroll.save()
form.save_m2m()
return HttpResponseRedirect(reverse('riding_schedule:view_events'))
forms.py
class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = ['title', 'start', 'end', 'enrolled']
labels = {'text':''}
widgets = {
'enrolled': forms.CheckboxSelectMultiple()
}
You can try like this:
First, send the current user information to the Form when form is initiated:
#login_required
def enroll(request, event_id):
event = Event.objects.get(id=event_id)
if request.method != 'POST':
form = EventForm(instance=event, user=request.user) # <-- Here
else:
form = EventForm(instance=event, data=request.POST)
# ....
Then use this information in the Form like this:
class EventForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super(EventForm, self).__init__(*args, **kwargs)
if user:
self.fields['enrolled'].queryset = Rider.objects.filter(owner=user) # overriding the queryset for enrolled here
class Meta:
model = Event
fields = ['title', 'start', 'end', 'enrolled']
labels = {'text':''}
widgets = {
'enrolled': forms.CheckboxSelectMultiple()
}

what causes the weird "UNIQUE constraint failed: auth_user.username" error?

I try to insert data in user model into other model by one to one relationship. In specific, I want insert username,email and password attributes of User into other models.In Addtional, I intend to create both User model and other model in one form. So, I override the save method in modelform. It works partially and be able to insert data in both models and databases, except throw a UNIQUE constraint failed: auth_user.username error.
In models.py
class Staff(models.Model):
yes_or_no = ((True, 'Yes'),(False, 'No'))
male_or_female = ((True,'Male'),(False,'Female'))
user = models.OneToOneField(User, unique=True)
gender = models.BooleanField(default = True, choices = male_or_female)
birthday = models.DateField(default =None,blank = False, null = False)
created = models.DateTimeField(default=datetime.now, blank=True)
authorized = models.BooleanField(default=False,choices = yes_or_no)
store_id = models.ForeignKey(Store,default=1)
#property
def name(self):
return self.user.username
#property
def email(self):
return self.user.email
#property
def password(self):
return self.user.password
#property
def first_name(self):
return self.user.first_name
#property
def last_name(self):
return self.user.last_name
def __str__(self):
return self.user.username
In forms.py
class StaffForm(forms.ModelForm):
name = forms.CharField(max_length=100)
email= forms.EmailField(max_length=100, required=True)
password = forms.CharField(max_length=50)
store_id = forms.ModelChoiceField(queryset = Store.objects.all(),empty_label="--------") # select values ?
first_name = forms.CharField(required = True,max_length=100)
last_name = forms.CharField(required = True,max_length=100)
class Meta:
model = Staff
fields = ('gender','birthday','authorized','store_id')
widgets = {'authorized':forms.RadioSelect,
'gender':forms.RadioSelect,
'birthday':SelectDateWidget(years=range(date.today().year-50,date.today().year))
}
def save(self,*args,**kwargs):
Staff = super(StaffForm,self).save(commit=False)
user = User.objects.create(
username=self.cleaned_data['name'],
first_name=self.cleaned_data['first_name'],
last_name = self.cleaned_data['last_name'],
email= self.cleaned_data['email'])
user.set_password(self.cleaned_data['password'])
if self.cleaned_data['authorized']:
user.is_staff = True
Staff.user = user
Staff.save()
In views.py
#login_required(login_url='/dataInfo/login/')
def createstaff(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = StaffForm(request.POST or None)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
form.save()
return HttpResponseRedirect('/dataInfo/staff_view/')
# if a GET (or any other method) we'll create a blank form
else:
form = StaffForm()
return render(request, 'dataInfo/create_staff.html', {'form': form})

Django - ModelForm initial data from database

In my Django project i create an app to have additional information about registered users. So my model looks like this:
class UserProfile(models.Model):
class Meta:
verbose_name_plural = u'User Profile'
user = models.OneToOneField(User)
birthday = models.DateField(blank=True, null=True)
avatar = models.ImageField(upload_to='media/profile/avatar', blank=True, null=True)
name = models.CharField(blank=True, null=True, max_length=20)
surname = models.CharField(blank=True, null=True, max_length=50)
phone = models.CharField(blank=True, null=True, max_length=12)
def __unicode__(self):
return '%s' % self.user
In user profile i create modelform where user can fill or edit the fields from UserProfile model:
class ExtraProfileDataForm(ModelForm):
name = forms.CharField(label=(u'Enter your name'))
surname = forms.CharField(label=(u'Enter your surname'))
phone = forms.CharField(label=(u'Enter your phone'))
birthday = forms.DateField(label=(u'Enter birthday'))
avatar = forms.ImageField(label=(u'Enter avatar'))
class Meta:
model = UserProfile
fields = ('name', 'surname', 'phone', 'birthday', 'avatar')
def __init__(self, *args, **kwargs):
super(ExtraProfileDataForm, self).__init__(*args, **kwargs)
for key in self.fields:
self.fields[key].required = False
This is the view of the model form:
#login_required
def UserFullDataForm(request):
if request.method == 'POST':
form = ExtraProfileDataForm(request.POST)
if form.is_valid():
profile_user = request.user
user_profile = UserProfile(user=profile_user)
user_profile.name = form.cleaned_data['name']
user_profile.surname = form.cleaned_data['surname']
user_profile.phone = form.cleaned_data['phone']
user_profile.birthday = form.cleaned_data['birthday']
user_profile.avatar = form.cleaned_data['avatar']
user_profile.save()
return HttpResponseRedirect('/profile/')
else:
return render(request, 'profiles/extra_profile.html', {'form':form})
else:
form = ExtraProfileDataForm()
context = {'form':form}
return render (request, 'profiles/extra_profile.html', context)
But i want to load on ExtraProfileDataForm initial data from model UserProfile if the fields not empty. I searched how to do that on Django documentation website, but nothing found. Can somebody help me to understand how to do it? Thanks a lot.
You use the instance parameter.
Note that you are doing much more work than necessary here; most of your view can be cut.
#login_required
def UserFullDataForm(request):
try:
profile = request.user.userprofile
except UserProfile.DoesNotExist:
profile = UserProfile(user=request.user)
if request.method == 'POST':
form = ExtraProfileDataForm(request.POST, instance=profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/profile/')
else:
form = ExtraProfileDataForm(instance=profile)
return render(request, 'profiles/extra_profile.html', {'form':form})
Similarly, in your form, you don't need the overridden __init__ method because you're manually specifying all the fields anyway; you can add required=False on each one there. However, you could make this even shorter by adding the labels in the model definition; then your entire modelform could just be:
class ExtraProfileDataForm(ModelForm):
class Meta:
model = UserProfile
fields = ('name', 'surname', 'phone', 'birthday', 'avatar')
One final note: you're consistently using three-space indentation, which is a bit, well, odd. Most Python programmers prefer two or four.

About django, each user information save to database

I want to save the database attendance data daily of each user,
but my no error no saved why? please help me
this is my full code below:
this is my views.py:
def staffs(request):
args = {}
args.update(csrf(request))
args['staffs'] = User.objects.all()
return render_to_response("staffs.html", args)
def staffdetail(request, user_id=1):
user = get_object_or_404(User, pk=user_id)
return render_to_response("staffdetail.html",
{"user": User.objects.get(id=user_id) })
def attendance(request, user_id):
if request.method == "POST":
attendance = Attendance_data(user = request.user.id)
form = AttendancekForm(request.POST, instance = attendance)
if form.is_valid():
form.save()
return HttpResponseRedirect('/articles/get/%s' % user.id)
else:
form = AttendanceForm()
return render_to_response('attendance.html', context_instance = RequestContext(request, {'form': form}))
def leave_work(request, user_id):
if request.method == "POST":
leave_work = Leave_work(user = request.user.id)
form = Leave_workForm(request.POST, instance = leave_work)
if form.is_valid():
form.save()
return HttpResponseRedirect('/articles/get/%s' % user.id)
else:
form = Leave_workForm()
return render_to_response('leave.html', context_instance = RequestContext(request, {'form': form}))
So,i'm also add my models.py and forms.py here
this is my models.py:
class User(models.Model):
user_name = models.CharField(max_length=255)
first_kana = models.CharField(max_length=255)
last_kana = models.CharField(max_length=255)
employee_number = models.CharField(blank=True, max_length=22)
created_at = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.user_name
class Attendance_data(models.Model):
user_name = models.CharField(max_length=255)
employee_number = models.CharField(blank=True)
def __unicode__(self):
return self.user_name, employee_number
class Leave_work(models.Model):
user_name = models.CharField(max_length=255)
employee_number = models.CharField(blank=True, max_length=22)
def __unicode__(self):
return self.user_name, employee_unmber
this is my forms.py:
class ArticleForm(forms.ModelForm):
class Meta:
model = User
fields = ('user_name','first_kana', 'last_kana', 'employee_number')
user_name = forms.CharField( label="name",error_messages={'required': ''})
first_kana = forms.CharField(label="firstname",error_messages={'required': ''})
last_kana = forms.CharField(label="lastname",error_messages={'required': ''})
employee_number = forms.CharField(label="number", required=False)
class Attendance_dataForm(forms.ModelForm):
class Meta:
model = Attendance_data
fields = ('user_name','employee_number')
user_name = forms.CharField(label="name", error_messages={'required': ''})
employee_number = forms.CharField(label="number",error_messages={'required': ''})
class Leave_workForm(forms.ModelForm):
class Meta:
model = Leave_work
fields = ('user_name', 'employee_number')
user_name = forms.CharField(label="name", error_messages={'required': ''})
employee_number = forms.CharField(label="number", error_messages={'required': ''})
You are doing a lot of wrong thing in your views. If you look at your model Attendence_data, it has two fields user_name and employee_number. so its constructor would accept two arguments, user_name and employee_number or any other fields that are set not to be NULL and have no default value, so passing request.user.id to the its constructor would not make it a valid object. Same is the case with Leave_work model. So if you need to do this, you need to overload the default constructor.
But seems like you are not being able to understand the basic concepts of how Django works so I'd suggest you to go trough this tutorial as this will clear a lot of basic concepts.