model no iterable "create by user" django - python

I have a problem, when i try upload files I am trying show the user uploaded the file but not working.
My model is this:
class Document(models.Model):
id = models.AutoField(primary_key=True)
programa=models.CharField(max_length = 100)
materia=models.CharField(max_length = 50)
profesor=models.CharField(max_length = 50)
usuario=models.ForeignKey(Usuario)
add=models.DateTimeField ( auto_now = True )
archivo= models.FileField(upload_to="archivos/",storage=OverwriteStorage(),null = False)
def __unicode__(self):
return self.programa
class Meta:
db_table = u'utp_document'
My view is:
#login_required(login_url='/')
def upload(request):
if request.method=='POST':
form=DocumentForm(request.POST,request.FILES,)
if form.is_valid():
instances = form.save(commit=False)
for instance in instances:
instance.usuario = request.user
instance.save()
return HttpResponseRedirect('/menu/')
else:
form=DocumentForm()
return render_to_response('formulario_modal.html', {'form': form}, context_instance=RequestContext(request))
I followed this post Django - Auto populate created_by field outside django admin using form.
and this my form.py:
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
exclude = ('usuario',)
The problem is what i try new upload file get this error:
'Document' object is not iterable
What am I doing wrong?

form.save() returns a single modal instance:
instance = form.save(commit=False)
instance.usuario.user = request.user
instance.save()
FYI, in the post you've linked a formset is used which is the reason for a loop.

Related

Django pass user id before form is submitted

I am working on a Django-Tenant (Multi-Tenant) application. I am writing the script to create the subdomain. I am trying to get it to where created_by is set to the current users id that is logged in. How can I get current user ID to populate the created_by field?
views.py
class CreatePortal(View):
def get(self, request):
form = CreatePortalForm()
return render(request, "registration/create_portal.html", {"form": form})
def post(self, request):
form = CreatePortalForm(request.POST)
if form.is_valid():
getDomain = form.cleaned_data.get('name')
instance = form.save(commit=False)
tenant = Client(schema_name=getDomain, name=getDomain, created_by=**[NEED USER ID HERE]**)
tenant.save()
domain = Domain()
domain.domain = (getDomain + ".example.com:8000")
domain.tenant = tenant
domain.is_primary
domain.save()
with schema_context(tenant.schema_name):
instance.save()
redirect = 'http://' + getDomain + '.example.com:8000'
return HttpResponseRedirect(redirect)
return render(request, "registraton/create_portal.html", {"form": form})
forms.py
class CreatePortalForm(forms.ModelForm):
class Meta:
model = Client
fields = ["name"]
models.py
This is the line that I am working with models.py
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
I also get an error if it is not User type and if I do not pass an actual number for id, Field 'id' expected a number but got datetime.datetime
I have tried this as well:
user = request.user.id
tenant = Client(schema_name=getDomain, name=getDomain, created_by=user)
but then get this error:
Cannot assign "1": "Client.created_by" must be a "User" instance.
I am not sure how to pass the current logged in Users ID to populate the created_by form field. Any and all help is appreciated. I am still learning Django.

associate the user with the post Django and MySQL

I am trying to associate the user with the post. I have two models students is for user and sublists is for user posts with a foreign key(author). I am using MySQL database and using forms to store data into them. when my form.author execute in my HTML file it gives me a list of ids for all users in the databse but I am already logged in and i want to post as the logged in user without choosing. If remove it says my form is not valid which make sense since im not inputing for form.author.Since I'm using MySQL, I'm not using the built-in User authentication method, but instead comparing both email and password with the login form input. Spend too much time on this but hard to get around with this one. Any help would be appreciated
my views.py look like this
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
try:
form.save()
messages.success(request, ' Subscirption Saved')
name = sublist.objects.get(name=name)
return render (request, 'subscrap/main.html', {'sublist': name})
except:
pass
else:
messages.success(request, 'Error')
pass
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
#login_required(login_url='login')
#cache_control(no_cache=True, must_revalidate=True, no_store=True)
def main(request):
return render(request, 'subscrap/main.html')
def mod(request):
student = students.objects.all()
return render(request, 'subscrap/mod.html' , {'students': student})
My Models.py
class students(models.Model):
fname = models.CharField(max_length=50)
lname = models.CharField(max_length=50)
password = models.CharField(max_length = 50 , null = True)
passwordrepeat = models.CharField(max_length = 50, null = True)
email = models.EmailField(max_length=150)
class Meta:
db_table = "students"
class sublist(models.Model):
author = models.ForeignKey(students, related_name='sublist' ,on_delete=models.CASCADE)
name = models.CharField(max_length=150)
cost = models.IntegerField(default = 0)
renewalcycle = models.IntegerField(default = 0)
class Meta:
db_table = "sublist"
Since I'm using forms here's my forms.py
lass StudentForm(forms.ModelForm):
class Meta:
model = students
fields = "__all__"
class Studentlogin(forms.Form):
email = forms.EmailField(max_length=150)
password = forms.CharField(max_length = 50, widget=forms.PasswordInput)
class Sublist(forms.ModelForm):
class Meta:
model = sublist
fields = "__all__"
Exclude the Author from the Sublist form:
class Sublist(forms.ModelForm):
class Meta:
model = sublist
exclude = ['author']
In the addnew method, you associate the .instance.author with the request.user:
#login_required(login_url='login')
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
form.instance.author = request.user
form.save()
messages.success(request, ' Subscirption Saved')
return redirect('some_view')
else:
messages.error(request, 'Error')
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
Note: Models in Django are written in PascalCase, not snake_case,
so you might want to rename the model from sublist to Sublist.
Note: Usually a Form or a ModelForm ends with a …Form suffix,
to avoid collisions with the name of the model, and to make it clear that we are
working with a form. Therefore it might be better to use SublistForm instead of
Sublist.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the students directly. For more information you can see the referencing the User model section of the documentation.

Django forms - object has no attribute error when trying to reference one of the form fields

Well this is really confusing to me, whenever I execute the view I get an error at x = form.file_name form has no attribute file_name. However, when I comment out the line x = form.file_name the html {{form.file_name}} does not return an error and a file browser is outputted to the page. How come form.file_name returns an error when executed in views.py but not in upload.html?
upload.html
{{form.file_name}}
views.py
def upload(request):
form = CsvForm(request.POST or None, request.FILES or None)
x = form.file_name
return render(request, 'upload/upload.html', {'form' : form})
forms.py
class CsvForm(forms.ModelForm):
class Meta:
model = Csv
fields = ('file_name', 'public')
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Csv(models.Model):
file_name = models.FileField(upload_to='csvs', max_length = 100)
public = models.BooleanField(default = False)
user = models.ForeignKey(User, on_delete = models.CASCADE, null = True)
def __str__(self):
return "File id: {}".format(self.id)
Well this because behind the scene form saves the bound fields using __getitem__.
So to access correctly the bound field:
form["file_name"]
If you want to access the field:
form.fields["file_name"]

Django using a modelform to update an instance of model

I have the following model in Django which I use to store data about medicines.
class Medicine(models.Model):
Medicine_Name = models.CharField(max_length=100)
User_Associated = models.ForeignKey(User, on_delete=models.CASCADE)
Tablets_In_Box = models.IntegerField()
Dose_in_mg = models.IntegerField()
Dose_Tablets = models.IntegerField()
Number_Of_Boxes = models.IntegerField()
Last_Collected = models.DateField()
def __str__(self):
return self.Medicine_Name
def get_absolute_url(self):
return reverse('tracker-home')
I am trying to create a model form where a user can update the last collection of one of their medicines. Here is what I began with.
class CollectionForm(forms.ModelForm):
class Meta:
model = Medicine
fields = ['Medicine_Name', 'Number_Of_Boxes', 'Last_Collected']
I do not understand how I can call an instance of my model based on the 'Medicine_Name' from the field. In other words, I need the user to be able to select the correct medicine from a dropdown menu, and then the form must update the 'Last_Collected', and 'Numer_Of_Boxes' fields on my Medicine model.
https://docs.djangoproject.com/en/2.1/topics/forms/modelforms/#the-save-method
It seems this contains relevant information, but I struggle to see how to use it in this instance. How can I correctly get the instance of the medicine form I need, based on the user input in the form? Furthermore how can I use the save method in my views to make sure the database gets updated correctly?
EDIT Added view for the form:
def update(request, pk):
instance = Medicine.objects.get(id=pk)
if request.method == 'POST':
form = CollectionForm(user=request.user, instance=instance, data=request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.User_Associated = request.user
instance.save()
else:
form = CollectionForm()
context = {'form': form}
return render(request, 'tracker/medicine_collection.html', context )
**EDIT
views:
def update(request, pk):
instance = Medicine.objects.get(id=pk)
if request.method == 'POST':
form = CollectionForm(instance=instance, data=request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.User_Associated = request.user
instance.save()
return redirect ('/')
....
This is based on updating the instance of the specific user. This tutorial helpt me achieve the same thing.
https://youtu.be/EX6Tt-ZW0so
Tried a different approach (class based views - UpdateView) I just learned here on SO. Did not test it but I think its a step in the right direction.
class UpdateMedicine(LoginRequiredMixin, UpdateView):
model = Medicine #call the model you need to update
fields = ['Medicine_Name', 'Number_Of_Boxes', 'Last_Collected'] #specify the fields you need to update
template_name_suffix = 'medicine_update_form' #specify the template where the update form is living
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update(
user=self.request.user, #get the current logged in user
instance=get_object_or_404(Medicine, pk=self.kwargs['pk']) #get the pk of the instance
)
return context
def form_valid(self, form):
form.instance.medicine = get_object_or_404(Medicine, slug=self.kwargs['pk'])
return super().form_valid(form) #saves the updates to the instance
def get_success_url(self):
return reverse('medicine-collection') #name of the url where your 'tracker/medicine_collection.html is living
Link the appropriate templates and urls to the above example and try some things yourself.
Link to the django docs:
https://docs.djangoproject.com/en/3.0/ref/class-based-views/generic-editing/
Good luck!

(Django) By updating the UserProfile, the image is not saving correctly

I made a view, to update a userprofile. When uploading an image the image is saved correctly, but when updating the profile again, the image is not saved anymore, how can I solve that problem? I am glad for any help!
my class UserProfile looks like this:
class UserProfile(models.Model):
user = models.OneToOneField(User)
bio = models.TextField(max_length=500, blank = True, default=('keine Angabe'), null=True)
image = models.FileField(null=True, blank=True)
facebook = models.CharField(max_length=200, null=True,default=('keine Angabe'))
def get_absolute_url(self):
return reverse('gaestebuch:result', args=[str(self.id)])
def __unicode__(self):
return self.user.username
#property
def get_content_type(self):
instance = self
content_type = ContentType.objects.get_for_models(instance.__class__)
return content_type
I use two views:
def update_profile(request):
userProfile = UserProfile.objects.get(user=request.user)
form = UserProfileForm(initial={'bio': userProfile.bio, 'image' : userProfile.image, 'facebook': userProfile.facebook})
return render_to_response('gaestebuch/update_profile.html', {'form':form}, RequestContext(request))
#login_required
def send_update_profile(request):
if request.method == 'POST':
#form = UserProfileForm(request.POST)
form = UserProfileForm(request.POST or None, request.FILES or None)
if form.is_valid():
userProfile = UserProfile.objects.get(user=request.user)
bio = form.cleaned_data['bio']
userProfile.bio = bio
image = form.cleaned_data['image']
userProfile.image = image
facebook = form.cleaned_data['facebook']
userProfile.facebook = facebook
userProfile.save()
return redirect('the url' + str(userProfile.id))
else:
form = UserProfileForm()
return redirect('/user/send_update_profile')
This is my form:
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('bio','image','facebook',)
If there is anything else necessary to ad, I am happy to add that.
I am glad for any help!
Since you are using a ModelForm subclass instead of a Form subclass you should make use of it's functionality, particularly the save method.
Every ModelForm also has a save() method. This method creates and
saves a database object from the data bound to the form. A subclass of
ModelForm can accept an existing model instance as the keyword
argument instance; if this is supplied, save() will update that
instance. If it’s not supplied, save() will create a new instance of
the specified model
Thus your code ca be simplified as
form = UserProfileForm(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
return redirect('the url' + str(userProfile.id))
else:
return render_to_response(
'gaestebuch/update_profile.html', {'form':form}, RequestContext(request))
On a side note, when writing new django code use render instead of render_to_response as render_to_response is planned to be deprecated in the future and eventually removed.

Categories