so i am learning Django and making a todo application but i am stuck with a problem. I am storing every task on sqlite3 database(default by django) with models but when anyone store any task it is also visible to other person also how can i fix that?
if you have any alternative solution for that you can also tell that like how to use cookies or anything
models.py:-
from django.db import models
# Create your models here.
class Task(models.Model):
title = models.CharField(max_length=200)
completed = models.BooleanField(default=False, blank=True, null=True)
def __str__(self):
return self.title
Store who the task belongs to,
class Task(models.Model):
title = models.CharField(max_length=200)
completed = models.BooleanField(default=False, blank=True, null=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
You will have to store the user when creating/updating the Task
For instance,
task = Task.objects.create(title=title, user=user)
Now when you need to show the tasks, show only relavant tasks
tasks = Task.objects.filter(user=request.user)
Related
I was developing a chat system with channels and have this models for a thread (some attributes removed for simplicity's sake):
class Thread(models.Model):
name = models.CharField(max_length=50, null=True, blank=True)
users = models.ManyToManyField('auth.User')
I realized it is also possible to implement it like this:
class Thread(models.Model):
name = models.CharField(max_length=50, null=True, blank=True)
class ThreadUsers(models.Model):
thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
What are the advantages/disadvantages of using one over the other?
All what you do - is the same. For your last example with custom M2M through model you can add M2M declaration users in Thread:
class Thread(models.Model):
name = models.CharField(max_length=50, null=True, blank=True)
# M2M declaration, which use your ThreadUsers
users = models.ManyToManyField('auth.User', through='ThreadUsers' )
class ThreadUsers(models.Model):
thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
Pros:
You create model self
you can change behavior your M2M connection manually.
You can add additional fields in M2M through connection.
You have full control of this model.
Cons:
problem with m2m connections in django admin.
too much additional code, you can get a hard-to-find errors.
some fields/widgets don't want to work with M2M.through.
all was happened is your problem, this is not tested. Auto-through relation is tested in box.
we have in our projects 50/50 M2M-autothrough vs M2M-manualthrough. if I want to have more control on the models and realations - i use custom through.
p.s. in M2M-autothrough case Django created SomethingLikeYourThreadUsers Model and Table automatically.
I searched through stackoverflow about this particular scenario, but could not find a concrete answer, so i'm posting this.
So my problem is that i need to display specific records to a specific user in Django Admin. I'm aware that i can get the concrete logged in user through the get_queryset method extracting it from the request object. But the issue is i need to look through 6 tables to get to the information about the user of the recommendations so i could know which recommendation to display to him.
For example, if the records i need to display come from a Recommendation table, it has a reference to TableA, which has a reference to TableB .... which has a reference to TableF which has a reference to the User.
I'm aware i could do this by executing a plain SQL query with multiple joins, but my guess is that there must be a pythonic or Django sophisticated solution to this. But i may be wrong.
The model is unfortunately not in my control, nor i can change it, so i'm left to work with the state of the model that there is.
Thanks in advance.
EDIT: Unfortunately, i can't share details of it, but i can share the general look of it. So i think this should be enough to have a picture of my problem.
from django.db import models
from django.contrib.auth.models import User
class TableF(models.Model):
information = models.CharField(max_length=256, null=False)
user = models.ForeignKey(User, on_delete=models.CASCADE)
class TableE(models.Model):
information = models.CharField(max_length=256, null=False)
tableF = models.ForeignKey(TableF, on_delete=models.CASCADE)
class TableC(models.Model):
information = models.CharField(max_length=256, null=False)
tableEs = models.ManyToManyField(TableE, through='TableD')
class TableD(models.Model):
information = models.CharField(max_length=256, null=False)
tableC = models.ForeignKey(TableC, on_delete=models.CASCADE)
tableE = models.ForeignKey(TableE, on_delete=models.CASCADE)
class TableA(models.Model):
information = models.CharField(max_length=256, null=False)
tableCs = models.ManyToManyField(TableC, through='TableB')
class TableB(models.Model):
information = models.CharField(max_length=256, null=False)
tableA = models.ForeignKey(TableA, on_delete=models.CASCADE)
tableC = models.ForeignKey(TableC, on_delete=models.CASCADE)
class Recommendation(models.Model):
information = models.CharField(max_length=256, null=False)
tableA = models.ForeignKey(TableA, on_delete=models.CASCADE)
you can use a middleware to include de user to the thread locals and catch this user from get_queryset in the model manager.
from threading import local
_thread_locals = local()
def get_current_user():
return getattr(_thread_locals, 'user', None)
class ThreadLocals(object):
#staticmethod
def process_request(request):
_thread_locals.user = getattr(request, 'user', None)
in the settings
MIDDLEWARE = [
...
'path.to.file.ThreadLocals',
]
from your.path import get_current_user
class TableFManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(creator=get_current_user())
class TableF(models.Model):
information = models.CharField(max_length=256, null=False)
user = models.ForeignKey(User, on_delete=models.CASCADE)
objects = TableFManager()
another less invasive option could be to rewrite the get_queryset in the admin class. there you already have the user in the request
def get_rec_user(user):
tes = TableE.objects.filter(tableF__in=TableF.objects.filter(user=user))
aes = TableB.objects.filter(tableE__in=tes).values_list('tableA_id', flat=True)
return Recommendation.objects.filter(
tableA__in=TableA.objects.filter(id__in=aes)
)
What I currently have in my models is this:
class Project(models.Model):
project_name = models.CharField(max_length=255, unique=True, blank=False)
def __str__(self):
return str(self.project_name)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
role = models.CharField(choices=ROLE_CHOICES, max_length=255, default='Agent')
Now my question is: Users should be able to have multiple Projects - so I obviously can't use a OneToOne-Field in the Profile-Model.
Later I want to use it for example to just show a user news which are only related to the projects he participates in.
What would be the best strategy to make this possible? Any input is highly appreciated.
Use ManyToMany on project.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
role = models.CharField(choices=ROLE_CHOICES, max_length=255, default='Agent')
project = models.ManyToManyField(Project)
This way one profile can have as many project as he/she wants
On your view you can use this field to filter based on project
Usecase
The app that I am developing is about linking startup, job seekers and investors. Sorry I could not give
the name still though I have developed already around 40% :) .There will be three entities. One
is Startup account, Enduser account and Investor account. I am thinking of adding follow/unfollow feature where
Enduser can follow Startup and vice-versa
Startup can follow Investor and vice-versa
Enduser cannot follow other enduser and enduser cannot follow investor
For this how should I model my application
Here is the model for the entities I talked about
Enduser Model
class UserSetting(models.Model):
user = models.OneToOneField(User)
job_interest = models.ManyToManyField(Category, related_name='user')
is_email_notification = models.BooleanField(
default=True, help_text="Email me job recommendations based on my interests and preferences")
class Meta:
verbose_name = 'User Setting'
verbose_name_plural = 'User Settings'
def __str__(self):
return self.user.username
Startup Model
class Startup(models.Model):
name = models.CharField(max_length=200, unique=True,
blank=False, null=False)
slug = models.SlugField(unique=True)
description = models.CharField(max_length=400)
Investor Model
class Investor(models.Model):
investor = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=200, blank=False,
null=False, help_text='Full Name')
slug = models.SlugField(max_length=200, unique=True)
contact_email = models.EmailField(null=True, blank=True)
# for now I have done like this
followers = models.ManyToManyField(
User, related_name='followers', blank=True)
For now, you can see I have included the followers field in the Investor but I need the follower system in the startup as well so that enduser can follow startup and vice-versa. Also in following investor only startup can follow but enduser should not.
What is the best possible solution for this?
It sounds like you are looking to build junction objects. You want to register Users against those objects. So I would probably redesign your data model a little. Here are my thoughts:
Investors are a group of users under a name (Pasadena Angels, XYZ Venture Partners, etc)
Startup is a company with a group of users
End-User is a singular User
But django authenticated Users can be "Investors", "Startup Employees", or "End Users". AND it is more than likely that Angel Investors are Executive Employees at a Startup. And it's possible, actually it sounds desireable that over time an EndUser becomes a Startup Employee.
Therefore I'd do something like this:
class EndUser(models.Model):
user = models.OneToOneField(User)
...
class Startup(models.Model):
name = models.CharField(max_length=100)
...
class StartupEmployee(models.Model):
user = models.ForeignKey(User)
startup = models.ForeignKey(Startup)
...
class InvestmentFirm(models.Model):
name = models.CharField(max_length=100)
...
class Investor(models.Model):
user = models.ForeignKey(User)
firm = models.ForeignKey(InvestmentFirm)
...
class Follower(models.Model):
user = models.ForeignKey(User)
startup = models.ForeignKey(Startup, blank=True, null=True)
firm = models.ForeignKey(InvestmentFirm, blank=True, null=True)
...
My thought process is that the data model does not need to control the logic of who can follow who. My thought process is that the application will have separate views which can control who can see what. In other words the data model shouldn't prevent end-users from following other end-users. That should be part of the UI/UX.
Thats my quick hack at a recommendation.
I have a Users and Jobs. If some User creates a Job, then and only then he/she can edit some information of this Job.
So he visits the url .../job/update/<id>. If the Job is created by him (the User is a ForeignKey in Job, then he can modify data. Otherwise he gets 404 error.
In view function, I would probably get current Users id and compare this id to Jobs ForeignKey.
But there are many patterns and shortcuts in class views so I'm curious how to do that this way.
class EditOrderView(UpdateView):
model = Job
fields = ['language_from','language_to','level','short_description','notes',
'text_to_translate','file']
template_name = 'auth/jobs/update-order.html'
class Job(models.Model):
customer = models.ForeignKey(User, related_name='orders', help_text=u"Zákazník")
translator = models.ForeignKey(User, related_name='jobs', null=True, blank=True, help_text=u"Prekladateľ")
price = models.FloatField(null=True, blank=True, help_text=u"Cena")
language_from = models.ForeignKey(Language, related_name='jobs_from', null=True)
language_to = models.ForeignKey(Language, related_name='jobs_to', null=True)
...
It looks like you can override .get_object() method and include your own logic:
from django.shortcuts import get_object_or_404
class EditOrderView(UpdateView):
model = Job
...
def get_object(self, queryset=None):
return get_object_or_404(self.model, pk=self.kwargs["pk"], customer=self.request.user)