I have seen many solutions for this on here but I can't seem to get any working as I am also new to django. Essentially as of now my files are uploading correctly by a user to media/documents but when I try to download the files from the directory, in terminal I get 404 and I end up downloading an empty file. Say the original file is "test.txt", right now it is downloading an empty "documents_test.txt". As of right now this is what I have for my code and how I am trying to download within my template.
models.py
class Program(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
description = models.CharField(max_length=128)
upload = models.FileField(upload_to='documents/')
category = models.ForeignKey(ProgramCategory, on_delete=models.CASCADE)
is_public = models.BooleanField()
views.py
def programs(request):
# Create some default categories if there aren't any.
if (not ProgramCategory.objects.all()):
ProgramCategory.objects.create(category="Hobby")
ProgramCategory.objects.create(category="School")
ProgramCategory.objects.create(category="Work")
'''if (request.method == "GET" and "toggle_completed" in request.GET):
id = request.GET["toggle_completed"]
task = Task.objects.get(id=id)
task.is_completed = not task.is_completed
task.save()'''
if (request.method == "GET" and "delete" in request.GET):
id = request.GET["delete"]
Program.objects.all().filter(id=id).delete()
return redirect("/programs/")
if (request.method == "POST"):
try:
user_profile = UserProfile.objects.filter(user=request.user).get()
except:
user_profile = UserProfile()
user_profile.user = request.user
#user_profile.tasks_view_hide_completed = False
#form = HideCompletedTasksForm(request.POST, instance=user_profile)
if (form.is_valid()):
form.save()
user_profile = UserProfile.objects.filter(user=request.user).get()
#hide_completed_form_data = HideCompletedTasksForm(instance=user_profile)
#except:
#hide_completed_form_data = HideCompletedTasksForm()
#hide_completed = hide_completed_form_data["tasks_view_hide_completed"].value()
#if (hide_completed):
#table_data = Task.objects.select_related().filter(user=request.user, is_completed=False)
else:
table_data = Program.objects.all().filter(user=request.user)
#filename = Program.objects.all().filter(user=request.user).values_list('upload')
context = {
#"hide_completed_form_data": hide_completed_form_data,
"table_data": table_data,
}
template(programs.html)
{% for row in table_data %}
<tr>
<td>{{ row.upload }}</td>
<td>{{ row.description }}</td>
<td>{{ row.category }}</td>
.
.
.
<td>
<a class="btn btn-primary" href="/programs/edit/{{ row.id }}/">Edit</a>
<a class="btn btn-primary" href="#" onclick="confirmDeleteModal({{ row.id }})">Delete</a>
<a class='btn btn-primary' href="{{ row.upload.url}}" download="{{ row.upload.url}}"> Download</a>
</tr>
{% endfor %}
{% endif %}
Any help would be greatly appreciated.
Related
I have created an attendance system in Django but I cannot seem to retrieve all users that are currently present.
My code is displayed below:
Models:
class Meta:
model = User
fields = ("username", 'email', 'password1', 'password2')
class is_Present(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(default=datetime.date.today)
is_present = models.BooleanField(default=False)
class clocked_Time(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(default=datetime.date.today)
time = models.DateTimeField(null=True, blank=True)
signed_out = models.BooleanField(default=False)
views.py:
# Displays admin attendance portal functions
def attendance_portal(request):
if not request.user.is_authenticated:
messages.warning(request, f'Please sign in to mark attendance out')
return redirect('login')
elif not request.user.is_superuser or not request.user.is_staff:
messages.warning(request, f'Must be admin to access this feature')
return redirect('home')
elif request.user.is_superuser:
count_employees_all = count_employees() # shows count of employees
present_employee_all = present_employees() # shows count present employees today
present_employee_all_week = present_week_employees() # shows count present employees in last 7 days
# Gets the employees present today
today = datetime.today()
# Gets employees displayed and paginated
user = get_user_model()
user_list = user.objects.all()
p = Paginator(is_Present.objects.filter(date=today).filter(is_present=True).select_related('user').values('user__username'), 5)
page = request.GET.get('page', 1)
users = p.get_page(page)
try:
users = p.get_page(page) # returns the desired page object
except PageNotAnInteger:
# if page_number is not an integer then assign the first page
users = p.page(1)
except EmptyPage:
# if page is empty then return last page
users = p.page(p.num_pages)
# this_week_emp_count_vs_date()
# last_week_emp_count_vs_date()
return render(request, "users/adminReports.html",
{'count_employees_all': count_employees_all, 'present_employee_all': present_employee_all,
'present_employee_all_week': present_employee_all_week, 'user_list': user_list, 'users': users})
else:
messages.warning(request, f'Error - please see logs for details.')
return redirect(request, 'home')
HTML:
<div class="card" style="margin: 2em; background: lightcoral;border: solid 3px dimgrey; padding-bottom: 30px; width: 50%">
<div class="card-body">
<h4 style="text-align: center"> Employee's Present Today </h4><br />
{% for user in users %}
<table class="table align-left table-dark table-striped table-hover table-bordered">
<tbody>
<tr>
<td style="width: 25%;">{{ user.username }}</td>
</tr>
</tbody>
</table>
{% endfor %}
<div style="text-align: center;">
{%if users.has_previous %} {# whether the previous page exists #}
<button class="btn btn-outline-dark btn-sm">«</button> {# link to the prev page #}
{% endif %}
<span>{{users.number}}</span> {# the current page number #}
{%if users.has_next %} {# whether the next page exists #}
<button class="btn btn-outline-dark btn-sm">»</button> {# link to the next page #}
{% endif %}
</div>
There is currently one user present today, and it seems to grab the user as it inserts one table row, however it does not allow me to grab the username etc (please see image)
Seems that user.username was not getting referenced far enough. I was able to solve this by referencing using this:
user.user.username
user.user.username
I have previously figured out how to send and save notifications by many to many fields to send to users, now i can't specifically call the notifications by current user logged in i.d.
Models.py
class Notifications(models.Model):
id=models.AutoField(primary_key=True)
sent_to = models.ManyToManyField(CustomUser)
message = models.TextField(null=True)
message_reply = models.TextField(null=True)
created_at=models.DateTimeField(auto_now_add=True)
updated_at=models.DateTimeField(auto_now=True)
The notifications_sent_to is the created table after I created the many to many save
Notifications_sent_to table (which is not created in the models)
Notifications table (which stores the message)
Views.py
def add_notification(request):
notifs = Notifications.objects.all()
users = CustomUser.objects.filter(is_staff=True)
if request.method == 'POST':
form = AddNotifForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.message_reply = "none"
instance.save()
form.save_m2m()
sent_to = form.cleaned_data.get('sent_to')
messages.success(request, f'Message has been successfully sent .')
return redirect('add_notif')
else:
form = AddNotifForm()
context={
'notifs' : notifs,
'form' : form,
'users' : users,
}
template_name ='main-admin/add-notif.html'
return render(request, template_name, context)
Forms.py
class AddNotifForm(forms.ModelForm):
sent_to = forms.ModelMultipleChoiceField(
queryset=CustomUser.objects.filter(is_staff=True).exclude(is_superuser=True),
widget=forms.CheckboxSelectMultiple,
required=True)
class Meta:
model = Notifications
fields = ['sent_to', 'message']
Templates view
{% for sent_to_users in sent_to_users %}
<tr>
<td>{{ sent_to_users.id }}</td>
<td>{{ sent_to_users.sent_to }}</td>
<td>{{ sent_to_users.message }}</td>
<td>
{% if sent_to_users.message_reply == "none" %}
<button type="button" class="btn btn-primary reply_open_modal" data-bs-toggle="modal" data-bs-target="#replyModal">Reply</button>
{% else %}
{{ sent_to_users.message_reply }}
{% endif %}
</td>
<td>{{ sent_to_users.created_at }}</td>
</tr>
{% endfor %}
Scenario: I have some boxes (containers) I have some objects (samples) a sample can be split over many boxes, a box can contain many samples.
I want to be able to assign a sample to a box and remove a sample from a box.
I followed these tutorials 57-59, assigning friends to users, and got it working.
So I now try to adapt the code, so I need to change users to boxes/containers and friends to samples. Sounds simple enough. But I'm inexperienced with the quirks of Django and where the request.user is I can't seem to get the correct syntax. So here comes the code, first the code working from the tutorial, then my attempt at refactoring it.
I have 2 other tables/models Containers and Sample which the ContainerContent model fits inbetween.
# models.py (tutorial)
class Friend(models.Model):
users = models.ManyToManyField(User)
current_user = models.ForeignKey(User, related_name='owner', null=True, on_delete = models.PROTECT)
# container_id = models.ForeignKey(Container, null=True, on_delete = models.PROTECT)
#classmethod
def make_friend(cls, current_user, new_friend):
friend, created = cls.objects.get_or_create(
current_user=current_user
)
friend.users.add(new_friend)
#classmethod
def lose_friend(cls, current_user, new_friend):
friend, created = cls.objects.get_or_create(
current_user=current_user
)
friend.users.remove(new_friend)
# views.py
def change_friends(request, operation, pk):
friend = User.objects.get(pk=pk)
if operation == 'add':
Friend.make_friend(request.user, friend)
elif operation == 'remove':
Friend.lose_friend(request.user, friend)
return redirect('depot:allcontainer')
#urls.py
url(r'^container/(?P<operation>.*)/(?P<pk>\d+)/$', views.change_friends, name='change_friends'),
#html
...
<tbody>
{% for user in users %}
<tr>
{% if user not in friends %}
<!-- we will want to add an if stmt list if not in unassigned - need to think how to do this -->
<td>{{ container.container_id }}</td>
<td>{{ user.username }}</td>
<td> <a href="{% url 'depot:change_friends' operation='add' pk=user.pk %}" class="badge badge-primary" role="button">
<!-- container=container.container_id -->
<!-- container=container.container_id -->
<!-- <button type="button" class="btn btn-success">add</button> -->
>>
</a></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
...
...
<tbody>
<tr>
{% for friend in friends %}
<td><a href="{% url 'depot:change_friends' operation='remove' pk=friend.pk %}" class="badge badge-primary" role="button">
<<
</a></td>
<td>{{ friend.username }}</td>
</tr>
{% endfor %}
</tbody>
...
Below is my Attempt:
# models.py
class ContainerContents(models.Model):
sample = models.ManyToManyField('Sample')
current_container = models.ForeignKey(Container, null=True, on_delete = models.PROTECT)
#classmethod
def add_to_container(cls, current_container, new_sample):
sample, created = cls.objects.get_or_create(
current_container=current_container
)
sample.add(new_sample)
#classmethod
def remove_from_container(cls, current_container, new_sample):
sample, created = cls.objects.get_or_create(
current_container=current_container
)
sample.remove(new_sample)
# views.py - this one is causing me issues, the request.____
def change_container(request, operation, pk, fk='', sample_id=''):
container = Container.objects.get(pk=pk)
sample = Sample.objects.get(pk=fk)
# sample = Container.objects.get(container.sample_id=sample_id)
if operation == 'add':
ContainerContents.add_to_container(request.container, container)
elif operation == 'remove':
ContainerContents.remove_from_container(request.container, container)
return redirect('depot:allcontainer')
# urls.py
url(r'^change_container/(?P<operation>.*)/(?P<pk>\d+)/sample/(?P<fk>\d+)$', views.change_container, name='change_container'),
I suspect I need to pass the container id here otherwise there will not be any distinction between the containers.
# html
<tbody>
{% for unassigned in container_contents %}
<tr>
<!-- { if user not in friends } -->
<!-- we will want to add an if stmt list if not in unassigned - need to think how to do this -->
<td>{{ unassigned.area_easting }}.
{{ unassigned.area_northing }}.
{{ unassigned.context_number }}.
{{ unassigned.sample_number }}</td>
<td>{{ unassigned.sample_id }}</td>
<td></td>
<td> <a href="{ url 'depot:change_friends' operation='add' pk=user.pk }" class="badge badge-primary" role="button">
<!-- container=container.container_id -->
<!-- container=container.container_id -->
<!-- <button type="button" class="btn btn-success">add</button> -->
>>
</a></td>
<!-- { endif } -->
</tr>
{% endfor %}
</tbody>
...
...
<tbody>
<tr>
{% for contents in container_contents %}
<td><a href="{% url 'depot:change_container' operation='remove' pk=container.container_id fk=contents.sample_id %}" class="badge badge-primary" role="button">
<!-- <button type="button" class="btn btn-default">remove</button> -->
<<
</a></td>
<td>{{ contents.sample_id }}</td>
<td>{{ contents.area_easting }}.
{{ contents.area_northing }}.
{{ contents.context_number }}.
{{ contents.sample_number }}</td>
</tr>
{% endfor %}
</tbody>
...
--- Update ---
I should have included the view that generates the page, not the users/friends is still contained in it and will be removed once I get it working.
def detailcontainer(request, container_id):
container = get_object_or_404(Container, pk=container_id)
samples = container.samples.all()
# allsamples = container.samples.exclude(sample_id=samples)
allsamples = container.samples.all()
users = User.objects.exclude(id=request.user.id).order_by('-id')
friend = Friend.objects.get(current_user=request.user)
friends = friend.users.all().order_by('-id')
container_contents = container.samples.all()
# container_contents = Container.objects.get(current_container=samples)
return render(request, 'container/detailcontainer.html',
{'container':container,
'samples':samples,
'allsamples': allsamples,
'users': users,
'friends': friends,
'container_contents': container_contents,
})
It should cause issues because request does not have any attribute named container. In your tutorial example, it got the logged in user using request.user, because django assigns logged in user instance to the request(through middleware).
As you already have sample and container objects in your change_container view method, you can try like this:
if operation == 'add':
ContainerContents.add_to_container(container, sample)
elif operation == 'remove':
ContainerContents.remove_from_container(container, sample)
Update
Missed one thing, you need to change inside add_to_container and remove_from_container method as well:
#classmethod
def add_to_container(cls, current_container, new_sample):
container, created = cls.objects.get_or_create(
current_container=current_container
)
container.sample.add(new_sample)
#classmethod
def remove_from_container(cls, current_container, new_sample):
container, created = cls.objects.get_or_create(
current_container=current_container
)
container.sample.remove(new_sample)
Because sample is a ManyToMany Field making connection between CurrentContainer and Sample model.
Update 2
#classmethod
def remove_from_container(cls, current_container, new_sample):
from app_name.models import ContainerSample
c_sample = ContainerSample.objects.get(container=current_container, sample=new_sample)
c_sample.delete()
You are not referencing your m2m field in fetched object. You'll need to address sample field as following:
models.py:
#classmethod
def add_to_container(cls, current_container, new_sample):
containerContents, created = cls.objects.get_or_create(
current_container=current_container
)
containerContents.sample.add(new_sample)
#classmethod
def remove_from_container(cls, current_container, new_sample):
containerContents, created = cls.objects.get_or_create(
current_container=current_container
)
containerContents.sample.remove(new_sample)
and set proper variables to your model methods:
views.py
def change_container(request, operation, pk, fk='', sample_id=''):
container = Container.objects.get(pk=pk)
sample = Sample.objects.get(pk=fk)
# sample = Container.objects.get(container.sample_id=sample_id)
if operation == 'add':
ContainerContents.add_to_container(container, sample)
elif operation == 'remove':
ContainerContents.remove_from_container(container, sample)
return redirect('depot:allcontainer')
I am trying to make a form for user creation through django. The user(henceforth developer) can choose from a list of supervisors to get himself registered. Problem is, I am not getting the list of all the supervisors from the query. When I use objects.get(), I receive an error that 2 objects were received. That means that the queries are getting the rows from the database.
models.py
from django.db import models
class UserProfile(models.Model):
name = models.CharField(max_length=50,verbose_name="Name")
login = models.CharField(max_length=(25),verbose_name="Login")
password = models.CharField(max_length=100, verbose_name="Password")
phone = models.CharField(max_length=20, verbose_name="Phone number", null=True, default=None, blank=True)
born_date = models.DateField(verbose_name="Born date" , null=True,default=None, blank=True)
last_connection = models.DateTimeField(verbose_name="Date of last connection" , null=True, default=None, blank=True)
email = models.EmailField(verbose_name="Email")
years_seniority = models.IntegerField(verbose_name="Seniority", default=0)
date_created = models.DateField(verbose_name="Date of Birthday", auto_now_add=True)
def __str__(self):
return self.name
class Supervisor(UserProfile):
specialisation = models.CharField(max_length=50, verbose_name="Specialisation")
class Developer(UserProfile):
supervisor = models.ForeignKey(Supervisor, verbose_name="Supervisor")
The form view create_developer.py -
from django.shortcuts import render
from django.http import HttpResponse
from TasksManager.models import Supervisor, Developer
# View for create_developer
def page(request):
error = False
# If form has posted
if request.POST:
if 'name' in request.POST:
name = request.POST.get('name', '')
else:
error=True
if 'login' in request.POST:
login = request.POST.get('login', '')
else:
error=True
if 'password' in request.POST:
password = request.POST.get('password', '')
else:
error=True
if 'supervisor' in request.POST:
supervisor_id = request.POST.get('supervisor', '')
else:
error=True
if not error:
supervisor = Supervisor.objects.get(id = supervisor_id)
new_dev = Developer(name=name, login=login, password=password,supervisor=supervisor)
new_dev.save()
return HttpResponse("Developer added")
else:
return HttpResponse("An error as occured")
else:
supervisors_list = Supervisor.objects.all()
return render(request, 'en/public/create_developer.html')
template create_developer.html
{% extends "base.html" %}
{% block title_html %}
Create Developer
{% endblock %}
{% block h1 %}
Create Developer
{% endblock %}
{% block article_content %}
<form method="post" action="{% url 'create_developer' %}" >
<table>
<tr>
<td>Name</td>
<td>
<input type="text" name="name" />
</td>
</tr>
<tr>
<td>Login</td>
<td>
<input type="text" name="login" />
</td>
</tr>
<tr>
<td>Password</td>
<td>
<input type="text" name="password" />
</td>
</tr>
<tr>
<td>Supervisor</td>
<td>
<select name="supervisor">
{% for supervisor in supervisors_list %}
<option value="{{ supervisor.id }}">{{ supervisor.name}}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Valid" />
</td>
</tr>
</table>
</form>
{% endblock %}
The supervisor select list should show the list. But I am getting an empty list there. The output of {{ supervisors_list|length }} is zero.
How to debug this?
You have to pass context to the html:
from django.shortcuts import render
from django.http import HttpResponse
from TasksManager.models import Supervisor, Developer
# View for create_developer
def page(request):
error = False
# If form has posted
if request.POST:
if 'name' in request.POST:
name = request.POST.get('name', '')
else:
error=True
if 'login' in request.POST:
login = request.POST.get('login', '')
else:
error=True
if 'password' in request.POST:
password = request.POST.get('password', '')
else:
error=True
if 'supervisor' in request.POST:
supervisor_id = request.POST.get('supervisor', '')
else:
error=True
if not error:
supervisor = Supervisor.objects.get(id = supervisor_id)
new_dev = Developer(name=name, login=login, password=password,supervisor=supervisor)
new_dev.save()
return HttpResponse("Developer added")
else:
return HttpResponse("An error as occured")
else:
supervisors_list = Supervisor.objects.all()
return render(request, 'en/public/create_developer.html', {'supervisors_list' : supervisors_list})
On my Django site, I have two models - one is Project, which a user can create, and one is Access, where a user can add other users for access to the project. The Access model contains a manytomanyfield where the additional users are stored. I can add users and remove users from this field and it works site-wide (ie if I add a user onto the project, then log into that user's account, I can see it) but if I add more than one collaborator, I will start to see multiple iterations of that project in my project stream. It seems to me that Django is showing me the project for each user in the access_list as opposed to just once.
Models.py:
class Project(models.Model):
project_name = models.CharField(max_length=200)
project_description = models.TextField(null=True, blank=True)
project_thumbnail = models.FileField(upload_to=get_upload_file_name, null=True, blank=True)
project_pubdate = models.DateTimeField(default=timezone.now)
created_by = models.ForeignKey(User)
def __unicode__(self):
return self.project_name
def save(self):
if not self.id and not self.project_description:
return
super(Project, self).save()
Access.objects.get_or_create(project=self)
if self.project_thumbnail:
size = 200, 200
image = Image.open(self.project_thumbnail)
image.thumbnail(size, Image.ANTIALIAS)
fh = storage.open(self.project_thumbnail.name, "w")
format = 'png' # You need to set the correct image format here
image.save(fh, format)
fh.close()
def get_project_thumbnail(self):
thumb = str(self.project_thumbnail)
if not settings.DEBUG:
thumb = thumb.replace('assets/', '')
return thumb
class Access(models.Model):
project = models.ForeignKey(Project)
access_list = models.ManyToManyField(User)
pubdate = models.DateTimeField(default=timezone.now)
Views.py:
#login_required
def projects(request):
thisuser = request.user
if Access.objects.filter(Q(access_list=thisuser) | Q(project__created_by=thisuser)).exists():
projects_by_username = Access.objects.filter(Q(access_list=thisuser) | Q(project__created_by=thisuser)).order_by('-project__project_pubdate')
else:
projects_by_username = None
return render_to_response('projects.html',
{'projects_by_username': projects_by_username,
'user': thisuser })
projects.html:
{% for project in projects_by_username %}
<table width="100%" cellpadding="5">
<tr>
<td width="25%" rowspan="3"><a href="/projects/get/{{ project.project.id }}">
{% if project.project.project_thumbnail %}
<img src="{% get_static_prefix %}{{project.project.project_thumbnail}}" width="150" /></td>
{% endif %}
</a></td>
<td width="75%" valign="top"><div class="heading16px">{{ project.project.project_name }}</div></td>
</tr>
<tr>
<td>{{ project.project.project_description }}</td>
</tr>
<tr>
<td> </td>
</tr>
</table>
{% endfor %}