Should I use a constraint? - django

I'm developing a Twitter-like system, and have a model to record who follows who. There are two fields and both fields are foreign keys and point to the User model.
Clearly you wouldn't want a follower-followee record duplicated, so I'm using the unique_together attribute in the inner Meta class, in order that the follower-followee pair is unique. Trying to violate this throws IntegrityError and 500 status code.
This feels like a "second line of defence" as my view and template code doesn't give a user the chance to follow someone twice.
Should I/can I do something similar to ensure you can't follow yourself?
The view and template that lists all users (each with a button to click to follow that user) does not list the currently logged in user, so there should be no opportunity to follow yourself. But I don't have anything equivalent to unique_together.

Dude, no.
I don't know why you're doing this, but assuming it isn't for a uni project with a lunatic professor, you're wasting your time.
That is, if he's not a lunatic he's not going to try and hack the following/followee . And so what if he does?
If its for a startup-idea, then spend less time solving this (trivial) problem and more time working on whatever business model or marketing or whathaveyou thing you need to do.
A little bug isn't going to be a show stopper.
If you're being contracted out, leave it as a bug and get the conteact extended to fix it :)
If you just want to fix this, just do a check in the model or the validation that the follower isn't the same as the followee

Related

Django: Proper way to display options to the user in this case

EDIT
Why would you downvote this question? Is there any question on SO that answers this that would show i didn't try to find it or google has answer to it that I missed? Or this is not the proper place to ask such questions?
This is a simple question asking for advice on how to display options keeping MY particular data structure in mind.
Please mention the reason for downvote.
ORIGINAL
I am trying to make my first website. I am using Django for it.
I need advice from you people regarding UI of a portion of my template.
I have a doctor user who will have to choose his clinic timings. So he has to choose from 7 days of week. Each day will have three shifts(Morning, Afternoon, Evening).
He may choose 1 or more days and then for each day he may choose 1 or more shifts and provide time for each shift.
How should I go about making options available to him so that it is easier for him to choose days-shifts-time and at the same time not clutter the UI?
One way is to display all 7 days then under each day display three shift and for each shift show time field. But I think this is too much on a modal popup.
Can you please suggest anything to make it simpler or show any screenshot from any site etc to get an idea about this.
To get an idea how my data is, you can refer to the image
I assume the "Clinic X" tables in your picture are actually m2m intermediary through tables? Meaning they contain a foreign key to both the doctor and clinic tables? I think to remember this from yesterday, when you still had an excerpt of your models.py in your post (I wanted to ask for more details, but I dont have the rep to comment yet).
You could make a view based on the "Clinic X" models. It would contain ModelChoice fields for selecting the right clinic and the doctor (or, if the doctor is actually the USER responsible for creating the data, have the doctor be fixed by checking request.user).
Then you could employ inlineformsets for the selection of days and start times.
If the 'shifts' are not mandatory, I would drop them entirely. You would have to code in checks that the user does not begin his afternoon shift at 2 am, etc.
Also, while I appreciate MS Paint art... you should try to model this with something like UML. While modelling may seem like a waste of time at first, they really help you understand your own project.

Why to extend Django User model? Is it bettet than using One-To-One Link With a User Model (Profile)?

this is my first question here, nevertheless S.O. is my main point of reference and support while developing my coding skills with Django.
Thanks on advance to all people who is part of SO!
My main question is: Under your experience, in which situations you needed to extend User Model? is it a common thing to do? ... all tutorials and blogs I have read says ... "for example, if you want to use an email insted a username". But this doesn't sound like a real reason to me, I haven't found other reasons than this.
If I want to use email as username I can create a user-creation form with a field to get username and allowing only emails. This will perfecly solve the problem right?
In my case I followed Django official recommendation:
it’s highly recommended to set up a custom user model, even if the
default User model is sufficient for you. This model behaves
identically to the default user model, but you’ll be able to customize
it in the future if the need arises.
So I did this:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
I'm ready, but ready for what? Please enlight me.
The second part of my question is: Let's imagine in the future I want to register more information about the users of my blog (country, gender, etc.) ... is it possible to create a profile table and point it with 1-to-1 relationship to my extended User model (which does nothing but is ready for the future)? Should I do it now that I have already dropped and created the database again?
Thanks a lot and sorry if I wrote too much.
Best regards,
goka.
If your website need to collect more user information, like, company, telephone, zip code. Also, maybe you need to classify user, like, level_1, level_2, something haven't be define in User model. Then, it's better to create a profile model.
If you already have some user registered, then you add new profile model, it may cause your future coding very messy, like, one year later, you or other software engineer may assume all User have 'profile', and directly use user.profile.something without checking whether profile exists or not or a user, that will throw exception.

Query on a Many to Many relationship using through in Django

I'm new in Django and I'm giving myself a big headhache trying to structure this query.
I have a BaseProfile connected with a OneToOne field to User.
I'm specializing the profile in CustomerProfile connected with a OneToOne field to BaseProfile.
A CustomerProfile has a ManyToMany relationship with other CustomerProfile (so itself) through a RelatedCustomer model.
In the RelatedCustomer I specify the from_customer and to_customer Foreign Keys.
Maybe with an image you can understand better.
My problem:
Given a user.id I need to know all the other user.id of the customers that he is connected to (so passing through from_customer and to_customer):
So basically, first I need to dig from User to RelatedCustomer using reverse lookup, take all the set, and then going back to know the user.id of each customer in the set.
EDIT2:
What I've reached so far:
# This gives me back a customer profile given a user.id (2)
cm = CustomerProfile.objects.get(base_profile__user=2)
# M2M lookup. Given one customer returns all the RelatedCustomer relations
# that he has as a part of the 'from' M2M
cm.from_photographer.all()
Chaining the previous two: given a user.id I obtain a queryset of CustomerRelated relations:
rel = CustomerProfile.objects.get(base_profile__user=2).from_photographer.all()
This gives me back something like:
[<CustomerRelated: from TestCustomer4 to TestCustomer2 >,
<CustomerRelated: from TestCustomer4 to TestCustomer3 >]
Where in this case the user having a user.id=2 is the TestCustomer4.
My question:
So far so good, but now having this set how can I get all the user.id of the to_customer?
That is, how do I get the user.id of TestCustomer2 and TestCustomer3?
Firstly, this is not how you query the database in django. Secondly (since you're learning), it would be good to point out that you can run dbshell to try out different things. And lastly, this kind of problem is described in the documentation.
I am telling you this, because as a beginner, I also felt that it was a little difficult to navigate through the whole thing. The best way to find things is just to use google, and add a django at the end.
I know how you feel, the documentation search sucks, right? Heh, I feel you, that is why you always search the way I described it. Once you get a hang of the documentation, you will feel that the documentation title page is a little more intuitive.
Okay, so now to the answer:
To access a ManyToMany, OneToOne or ForeignKey field, you need to use a __ commonly known as dunder.
So, this is how I would go about doing this. Please note that there are other ways, and potentially better ways of doing this:
thing_I_want = RelatedCustomer.objects.get(to_customer__id=2)
Note, however that if you wanted to get a list of customers you would use filter(). Here is an example (which uses number of purchases as an example):
things_I_want = RelatedCustomer.objects.filter(to_customer__no_of_purchases=16)
Also note that the great thing about filter is that you stack one filter on top of another. You can read more about these features in the documentation link I provide below.
That will get you what you want. Now, you might have more queries regarding this, and how it all works together. Not to fear, please click this documentation link to check it out.
EDIT
Seems like what you want to do can be done by django, but if you want to do it using sql, then that is possible too. For example, SomeModel.objects.raw("SQL_HERE"). The name of the tables are usually <app>_<model>.
However, what you are asking can also be done in django, using the ORM. But it will be tricky.
Ok, as usual whenever you get the answer it always look much more easier than what you were expecting.
I guess this worked for me:
User.objects.filter(base_profile__customer_profile__to_customer__in=
User.objects.get(id=2).base_profile.customer_profile.from_customer.all())
Many thanks to #Games Brainiac

Where to put business logic that spans multiple models in Django

You don't need to read all this post to help me answer the question, the rest of this post is only the context where the question came, but the general question is:
Where to put business logic that spans multiple models in Django?
some possibilities:
Some View? (I don't think so, it must work in the admin and several views, DRY)
Save methods in model/forms?(how?)
Clean methos in model/forms?(how?)
split the logic and use signals?(how?)
Other?
Context:
I have this models:
Department: Reference different departments in a company (risk, finance,IT,...)
Employee: May belongs to only one department for a period of time and then change to other department.
Project: Each Department can have multiple projects, and a project belongs to multiple departemnts.
Membership: intermediate table between the Employee and Department ManyToMany relationship that includes other fields like join_date and leave_date, important field are fk:Department, fk:Employee
History: intermediate table between Membership and Project that let me know which employee was involved in wish project wen he was working in some department, important fields are fk:Membership, fk:Project.
CurrentProjects: table that relates departments with the projects they are working on currently.
suppose I'm in the Django admin and I go the department Risk, and Risk has currently Project1 and Project2 assigned. when I add a new employee "Jhon Smith" (for example,using an inline form in Department) and press the save button, I want the model History gets updated with this information:
Membership table (only important fields):
pk Department Employee join_date leave_date
20 Risk Jhon Smith xxxx xxxx
History Table (only important fields):
Membership Project
20 Project1
20 project2
I mean when a new employee gets assigned to a new department all the actual projects from that department must be assigned to that Membership employee-department in the table History.
the question is where to put this logic in Django? as you can see this logic involves multiples models, some posibilities are:
In some view (I don think so, it must work in the admin interfase and in other places)
In the clean method of the Membership, Department or Employee model/form?
In the save method of the Membership, Department or Employee model/form?
I have to split the logic and use something like signals? (some example?)
Others?
I'm over complicating everything? =)
Considerations: It would be nice if the code could generate a valueerror at any point in the process and the user/admin could be able to see this error in the unbounded form.
I am just commenting on the aspect of where the logic should live. This all sounds like model logic to me. Django has a slightly mixed concept of MVC. When its purely data relation I believe its all model logic. I would recommend putting the methods as close to the model they affect as possible and simply make the smallest call possible from the triggering model.
If you are very concerned with decoupling the apps, then you could use signals. Instead of Model A knowing it needs to call XYZ during a save, it goes the other way. Model A just emits a signal. XYZ would be responsible for being connected to the signal. You can even make your signal definitions in a completely general project app, in which case neither the triggering or receiving Models know about eachothers actions. It just binds them.
There are some built in signals, such as before and after a save on a model, which means if you are looking for a save trigger you won't have to emit something custom. But lets say at various point of one models logic you need to emit a custom signal like "Name changed", you could emit your own.
Model A
import django.dispatch
name_changed = django.dispatch.Signal(providing_args=["name"])
class ModelA:
...
def foo:
# something happened here
name_changed.send(sender=self, name=the_name)
Model B, C, D
from myApp.modelA import name_changed
name_changed.connect(modelB.handle_name_change, dispatch_uid="my_unique_identifier")
name_changed.connect(modelC.handle_name_change, dispatch_uid="my_unique_identifier")
name_changed.connect(modelD.handle_name_change, dispatch_uid="my_unique_identifier")
Personally I have a habit of creating a utils.py module for apps that need some general "controller model" logic. They are more like actions or helpers.
Maybe the problem is that "history" table you have there. I don't know what kind of information you have in your Project table. But if every project have a start and end date, your history table is handling duplicate information. In this case, if you want to know in which project has worked an employee, you just need to know in which rage of dates this employee have worked for the department and then you need to find the projects of that department that were developed between the previous date range.
I hope you understand my point. If no, please tell me so i can explain it better (maybe with an example).
But as i understand your problem and your models, i think you don't need that history table. It will duplicate information...
So, if your Project model have this information (range of dates) the solution should live in a manager, because it is just a matter of find the information you want that live in multiple tables...
Hope it helps!

retrieving variable from intermed table

I need to retrieve institution name by going through an intermediate table. My view gets all the values except this one or at least it is not displaying in the template. Can someone please help with either revising my view or template statement?
http://dpaste.com/122204/
Thank you,
May
To debug these kinds of problems do the following.
Run the view function's processing separate from any template or any other parts of Django.
Either interactively or with a VERY simple script run your query. For example, use a simple script like this to explore your model and make sure your model really works.
from app.models import Contact, Institution, Whatever
results= Researchproject.objects.filter(restitlestrip__icontains='something').distinct()
for project in results:
print project.contact
print contact.institutionname
Note several things about your simple script and your template.
Case matters. Project != project.
Navigation matters. In the script shown above, contact is undefined. project.contact, however, is defined. Perhaps that's what you meant.
Your model appears incomplete. The Contactintermed table doesn't seem to be used anywhere in your query or view. It may have FK's to other tables, but you don't seem to have a sensible navigation from Project through Contact to Contactinterma to Institution.
Get your model to be correct in a stand-alone script. Add the template processing later.
Also, please post all the code here on StackOverflow. Chasing your code down all over the internet is a huge pain. It's far easier to simply ignore your question than it is to chase down your code.