I have a form, model and view and trying to show ModelChoiceField with filters
I wrote an init in my forms.py but when im trying to submit my form on html page i got an error:
"__init__() got multiple values for argument 'user' "
forms.py
class WorkLogForm(forms.ModelForm):
worklog_date = forms.DateField(label='Дата', widget=forms.DateInput(
attrs={'class': 'form-control', 'placeholder': 'Введите дату'}))
author = forms.EmailField(label='Автор',
widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email автора'}))
contractor_counter = forms.ModelChoiceField(queryset=CounterParty.objects.none())
contractor_object = forms.ModelChoiceField(queryset=ObjectList.objects.none())
contractor_section = forms.ModelChoiceField(queryset=SectionList.objects.none())
description = forms.CharField(label='Описание',
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Описание'}))
def __init__(self, user, *args, **kwargs):
super(WorkLogForm, self).__init__(*args, **kwargs)
counter_queryset = CounterParty.objects.filter(counter_user=user)
object_queryset = ObjectList.objects.filter(
Q(customer_guid__in=counter_queryset) | Q(contractor_guid__in=counter_queryset))
section_queryset = SectionList.objects.filter(object__in=object_queryset)
self.fields['contractor_counter'].queryset = counter_queryset
self.fields['contractor_object'].queryset = object_queryset
self.fields['contractor_section'].queryset = section_queryset
class Meta:
model = WorkLog
fields = (
'worklog_date', 'author', 'contractor_counter', 'contractor_object', 'contractor_section', 'description')
views.py
def create_work_log(request):
if request.method == 'POST':
form = WorkLogForm(request.POST, user=request.user)
if form.is_valid():
form.author = request.user
work_log = form.save()
return render(request, 'common/home.html')
else:
form = WorkLogForm(user=request.user)
return render(request, 'contractor/create_work_log.html', {'form': form})
In your forms init method you defined the parameters as:
def __init__(self, user, *args, **kwargs):
So your first parameter must be user instead of request.POST. So you can change
form = WorkLogForm(request.POST, user=request.user)
To
form = WorkLogForm(request.user, request.POST)
Related
My django project has multiple functions, one of them lets the user update its profile(User model"first_name, username and email" Profile model" bio and profile picture") this used to perfectly work until I added a follow sistem, it is like the whole Profile and User model doesnt exist anymore so when trying to edit those fields, the code returns a AttributeError: 'User' object has no attribute 'profile' error, saying this line of code on the views.py file is wrong form1 = UpdateProfileForm(request.POST or None, request.FILES, instance=request.user.profile), I think I am missing something on there or there is probably there is something wrong.
views.py
def profile(request, username=None):
profile, created = Profile.objects.get_or_create(user=request.user)
user = User.objects.get(username=username)
if username:
post_owner = get_object_or_404(User, username=username)
user_posts = Profile.objects.filter(user_id=post_owner)
is_following = Following.objects.filter(user=request.user, followed=user)
following_obj = Following.objects.get(user=user)
follower = following_obj.follower.count()
following = following_obj.followed.count()
else:
post_owner = request.user
user_posts = Profile.objects.filter(user=request.user)
args1 = {
'post_owner': post_owner,
'user_posts': user_posts,
'follower': follower,
'following': following,
'connection': is_following,
}
return render(request, 'profile.html', args1)
def edit_profile(request):
profile, created = Profile.objects.get_or_create(user=request.user)
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
form1 = UpdateProfileForm(request.POST or None, request.FILES, instance=request.user.profile)
if form.is_valid and form1.is_valid:
form.save()
form1.save()
return redirect('profile')
else:
form = EditProfileForm(instance=request.user)
form1 = UpdateProfileForm(instance=request.user)
args = {
'form': form,
'form1': form1,
}
return render(request, 'profile-edit.html', args)
models.py
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(upload_to='profile_pics', null=True, blank=True, default='default.png')
bio = models.CharField(max_length=400, default=1, null=True)
connection = models.CharField(max_length = 100, blank=True)
follower = models.IntegerField(default=0)
following = models.IntegerField(default=0)
def __str__(self):
return f'{self.user.username} Profile'
class Following(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
followed = models.ManyToManyField(User, related_name="followed")
follower = models.ManyToManyField(User, related_name="follower")
#classmethod
def follow(cls, user, another_account):
obj, create = cls.objects.get_or_create(user = user)
obj.followed.add(another_account)
print("followed")
#classmethod
def unfollow(cls, user, another_account):
obj, create = cls.objects.get_or_create(user = user)
obj.followed.remove(another_account)
print("unfollowed")
def __str__(self):
return f'{self.user.username} Profile'
forms.py
class EditProfileForm(UserChangeForm):
class Meta:
model = User
fields = (
'first_name',
'username',
'email',
)
exclude = ('password',)
class UpdateProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = (
'bio',
'profile_pic',
)
If you need to see more code please let me know;)
Try this:
def edit_profile(request):
profile, created = Profile.objects.get_or_create(user=request.user)
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
form1 = UpdateProfileForm(request.POST or None, request.FILES, instance=request.user.profile)
if form.is_valid() and form1.is_valid():
form.save()
form1.save()
return redirect('profile')
else:
form = EditProfileForm(instance=request.user)
form1 = UpdateProfileForm(instance=profile)
args = {
'form': form,
'form1': form1,
}
return render(request, 'profile-edit.html', args)
The solution I found temporarily to solve this problem is to just changed Profile's user object to OneToOneField and Following's user model to ForeignKey.
How can I write a url for a form using TemplateView. I wrote a method to validate and pass the company details through form. Using that form object that I'm trying to access the HTML fields.
Form.py
class CompanyDetailsForm(forms.Form):
class meta:
fields = ['company_name','contact_person','employee_count','email','mobile_number']
widgets = {
'comment':Textarea(attrs={'cols':30,'rows':5}),
}
company_name = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'company Name'}))
contact_person = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'Contact Person'}))
email = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'Email'}))
employee_count = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'Number Of Employee'}))
mobile_number = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'Mobile Number'}))
View.py
class GetCompanyView(TemplateView):
template_name = "astra/company_details.html"
form = CompanyDetailsForm()
def get_context_data(self,**kwargs):
context = super().get_context_data(**kwargs)
context['form']=self.form
return context
def company_details(request):
if request.method =="POST":
form = CompanyDetailsForm(request.POST)
if form.is_valid():
company_name = form.cleaned_data['company_name']
contact_person = form.cleaned_data['contact_person']
email = form.cleaned_data['email']
employee_count = form.cleaned_data['employee_count']
mobile_number = form.cleaned_data['mobile_number']
try:
form.save()
send_mail(company_name,contact_person,email,employee_count,mobile_number,['salesastra500#gmail.com'])
except BadHeaderError:
return BadHeaderError
return render(request,'astra/company_details.html',{'form':form})
else:
return render(request,'astra/company_details.html')
I want to run my company_details.html file using TemplateView. I'm not able to write the url for same. Plz suggest
TemplateView only have get method
def get(self, request, *args, **kwargs):
return render(request,self.template_name, {'form': self.form})
if you have get and post methods use FormView
I am using Django(2.0.7) UserCreationForm with three extra fields namely- first_name, last_name and email. I am getting the following error in the terminal window when I signup a new user (Though the user is created).
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: auth_user.username
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: auth_user.username
My forms.py is
class SignupForm(UserCreationForm):
alphabetic = RegexValidator(r'^[a-zA-Z]+$')
email = forms.CharField(max_length=254, required=True, widget=forms.EmailInput(attrs={'placeholder': 'Email Address', }))
first_name = forms.CharField(max_length=254, required=True, widget=forms.TextInput(attrs={'placeholder': 'First Name', 'style': 'text-transform:capitalize'}),
validators=[alphabetic])
last_name = forms.CharField(max_length=254, required=True, widget=forms.TextInput(attrs={'placeholder': 'Last Name', 'style': 'text-transform:capitalize'}),
validators=[alphabetic])
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')
widgets = {'username': forms.TextInput(attrs={'placeholder': 'Username'})}
def __init__(self, *args, **kwargs):
super(SignupForm, self).__init__(*args, **kwargs)
self.fields['password1'].widget = forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': 'Choose a Password'})
self.fields['password2'].widget = forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': 'Confirm the Password'})
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.save()
I have also tried overriding the default save method in the form, but that didn't work either. I have deleted my db multiple times and created fresh db but none has helped so far.
I am using a login modal in bootstrap. So my views.py is some what like this:-
def register_view(request):
data = dict()
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
login(request, user)
data['form_is_valid'] = True
else:
data['form_is_valid'] = False
else:
form = SignupForm()
context = {'form': form}
data['html_form'] = render_to_string('signup.html',
context,
request=request
)
return JsonResponse(data)
I have also tried adding the following lines in my settings.py :-
ACCOUNT_FORMS = {'signup':'accounts.forms.SignupForm',}
Maybe this will happen
form.save(commit=False)
I'm trying to let my users update their profile from the front-end allowing it to reflect at the django admin particularly updating of profile image. The change of user.first_name and user.last_name works fine except from the image which also doesn't reflect at the back end.
I think i'm missing something plus when the fields for firstname and lastname are empty it post as null I think I'd use an exception for that but i'm more concerned with the profile image. Please Help me I'm not getting it
here is my code
#views.py
def edit_user_profile(request, username):
user = request.user
form = EditProfileForm(request.POST or None, request.FILES, initial={'first_name': user.first_name, 'last_name': user.last_name})
if request.method == 'POST':
if form.is_valid():
# user.photo = UserExtended(photo=request.FILES['photo'] or None, )
photo = UserExtended.objects.get(user=user)
user.first_name = request.POST['first_name']
user.last_name = request.POST['last_name']
# username = request.POST['username']
photo.save()
user.save()
context = {
'form': form,
}
return render(request, 'accounts/profile_updated.html', context)
context = {
'form': form,
'username': username,
}
return render(request, 'accounts/edit_profile.html', context)
#model.py
#python_2_unicode_compatible # only if you need to support Python 2
class UserExtended(models.Model):
user = models.OneToOneField(User, related_name='user')
photo = models.ImageField(upload_to='media/user_media/users', verbose_name='Profile Picture',
default='/media/user_media/avatars/avatar.png', blank=True)
address = models.CharField(max_length=255)
phoneNumber = models.CharField(max_length=11)
class Meta:
verbose_name_plural = _("user")
def __str__(self):
return self.user.username
def image_tag(self):
if self.photo:
return mark_safe('<img src="/media/%s" width="150" height="150" />' % self.photo)
else:
return mark_safe('<img src="/media/user_media/avatars/avatar.png" width="150" height="150" />')
image_tag.allow_tags = True
image_tag.short_description = 'Profile Avatar'
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
user_extended = UserExtended(user=user)
user_extended.save()
post_save.connect(create_profile, sender=User)
#forms.py
class EditProfileForm(forms.ModelForm):
first_name = forms.CharField(label='First Name', widget=forms.TextInput(attrs={'class': 'form-control'}),
required=False)
last_name = forms.CharField(label='Last Name', widget=forms.TextInput(attrs={'class': 'form-control'}),
required=False)
# username = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}), required=True)
photo = forms.ImageField(label='Change Profile Image', required=False)
class Meta:
model = User
fields = ['photo', 'first_name', 'last_name', ] # 'username',
"""
Thank you in advance..
OK so while debugging with PyCharm, I discovered I was using the instance of my User class instead of my UserExtended which had the photo. I guess I got too comfortable since I was posting user.fist_name and user.last_name. This is the solution:
#views.py
def edit_user_profile(request, username):
user = request.user
form = EditProfileForm(request.POST or None, request.FILES, initial={'first_name': user.first_name, 'last_name': user.last_name})
if request.method == 'POST':
if form.is_valid():
#photo = UserExtended(photo=request.FILES['photo'] or None, )
user_extended = UserExtended.objects.get(user=user)
user.first_name = request.POST['first_name']
user.last_name = request.POST['last_name']
user_extended.photo = form.cleaned_data["photo"]
# username = request.POST['username']
user_extended.save()
user.save()
context = {
'form': form,
}
return render(request, 'accounts/profile_updated.html', context)
context = {
'form': form,
'username': username,
}
return render(request, 'accounts/edit_profile.html', context)
I have the following form:
class locationForm(forms.Form):
existing_regions= forms.ModelChoiceField(queryset=Region.objects.none(), label="Region Name", required=False)
region_name = forms.CharField()
location_name = forms.CharField()
street_address = forms.CharField()
city = forms.CharField()
zip_code = forms.CharField()
And the following update view for this form:
class UpdateLocation(View):
template_name = "dash/location_update_form.html"
def get(self, request, *args, **kwargs):
loc = kwargs['name']
try:
location = Location.objects.get(name=loc)
form = locationForm(instance=location)
return render(request, self.template_name, {'form': form,'location': location})
except (ValueError, ObjectDoesNotExist):
return redirect(reverse('geofence_manager'))
def post(self, request, *args, **kwargs):
loc = self.kwargs['name']
try:
location = Location.objects.get(name=loc)
form = locationForm (request.POST, instance=location)
if form.is_valid():
form.save()
else:
form = locationForm(request.POST, instance=location)
return render(request, self.template_name, {'location': location, 'form': form})
except (ValueError, ObjextDoesNotExist):
return redirect(reverse('location_manager'))
return redirect(reverse('location_manager'))
I am receiving an error in regards to 'instance' key word argument being used. I believe this has something to do with me not using a Modelform(I could be wrong). But I do not want to use a Modelform to construct my form, so is there a way I can get around this?
class locationForm(ModelForm):
class Meta:
model = Location
fields = '__all__'
in your view:
...
locationForm.base_fields['existing_regions'] = forms.ModelChoiceField(queryset= ...)
form = locationForm()