In a Django web app, let's say there is a prediction cast by the user Daniel. In the prediction, there is an accept button, any User can accept this prediction.
What I want to know is that if User Andrew accepts the offer, how can I store that in Daniel's prediction class? (If there is an accepted_by field in Daniel's prediction class, how can I change that field to Andrew, the actual User object not just a string, when User Andrew accepts that prediction)?
Thanks
In my models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
class gamble(models.Model):
prediction = models.BooleanField()
placement = models.PositiveIntegerField()
author = models.ForeignKey(User, on_delete = models.CASCADE)
accepted_by = models. **# this is what I need help with**
date_posted = models.DateTimeField(auto_now_add = True)
def get_absolute_url(self):
return reverse('page-home')
Related
I am trying to learn Django by creating something similar to Reddit. I have models for Post and User, and now I want to create one for "Community". I have looked at this post:
How to store an array of users in django?
However, I am unsure if the ManyToMany relationship is right here (perhaps it is).
I want the Community Model to contain Posts and Users registered with the Community. Each Community can have many posts, and each user can belong to multiple communities. When a Community is deleted, only delete the posts in that community, not the users. Similarly, when a User is deleted or a Post deleted, just remove that aspect from the Community.
If anyone has done this before or knows of a resource to learn this please let me know.
Here is my Post model so far. Note my Communities are called "Bands". Thus all of my references to "Community" will be "Bands" in my project.
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
# each class is its own table in the data
class Post(models.Model):
# each attribute is a different field in the data
title = models.CharField(max_length=100)
content = models.TextField()
# pass in the function as the default val, but do NOT execute yet!
date_posted = models.DateTimeField(default=timezone.now)
# foreign keys link two tables together
# on delete of User, we delete the user's post as well
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
Here is my Band model:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from home.models import Post
class Band(models.Model):
name = models.CharField(max_length = 100)
date_created = models.DateTimeField(default=timezone.now)
users = (settings.AUTH_USER_MODEL)
def __str__(self):
return "{self.name}"
I have two tables called User and Courses and I want to show the relationship between them my implementing a many-to-many relationship model. I want to implement 3 model classes in total as so:
# user/model.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
is_status = models.BooleanField(default=False)
is_newbie = models.BooleanField(default=False)
#courses/model.py
from django.db import models
from register.models import User
class Courses(models.Model):
course_name = models.CharField(max_length=100, null = False)
class StatusHasCourse(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
course = models.ForeignKey(Courses, on_delete=models.CASCADE)
How do I implement this so only the relationship between User that have is_status = True are only accessed in the StatusHasCourse model?
You can use the limit_choices_to=… parameter [Django-doc] to specify how to limit the choices. So in this specific case, we can make use of a Q-object [Django-doc] that specifies is_status=True:
from django.db.models import Q
class StatusHasCourse(models.Model):
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
limit_choices_to=Q(is_status=True)
)
course = models.ForeignKey(Courses, on_delete=models.CASCADE)
I have three models 'User', 'Assignment' and 'Feedback'. I am trying to setup a OneToMany assignment that can be accessed/viewed by all user accounts, where feedback can then be applied but only viewed by a OneToOneField user account. Here is some code to help explain what is currently happening.
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
# Create your models here.
class UserProfile(models.Model):
USER_TYPE_CHOICES = (
('Student', 'Student'),
('Lecturer', 'Lecturer'),
('Admin', 'Admin'),
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
uni_id = models.IntegerField(default=0)
type_user = models.CharField(max_length=20,
default='s',choices=USER_TYPE_CHOICES)
description = models.CharField(max_length=100, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
image = models.ImageField(upload_to='profile_image', blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile =
UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
# Assignment model
class Assignment(models.Model):
assignment_title = models.CharField(max_length=256)
assignment_id = models.IntegerField(default=0)
user = models.ManyToOneField(User, on_delete=models.CASCADE)
# Feedback model
class Feedback(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
I thought about maybe a foreign key connecting the assignments to a OneToOne field in the feedback model, but I'm really not sure. Any help would be greatly appreciated.
I would think that you'd want to relate the feedback to a specific assignment (of which there could be many), so you need an assignment foreign key in the Feedback model. Also, you'd need User as a foreign key rather than a one-to-one relationship as this would restrict you to one feedback per user.
class Feedback(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE)
If a user can only get one feedback per assignment, specify this in the Feedback model:
class Meta:
unique_together = ('assignment', 'user')
Extend the Feedback model with the actual feedback (grade, comments etc.) and possibly with a field for the originator of the feedback.
You can then create a view that only displays feedback for the request.user.
The Django tutorial offers quite a bit on views, as do many other helpful resources.
In Assignment, as an assignment can be given to multiple students and students will get multiple assignments in the course of their studies, you'd need a many to many relationship to User:
users = ManyToManyField(User)
(There is no ManyToOneField btw, that would be a ForeignKey.)
Here is my code:
from django.db import models
from django.contrib.auth.models import User
class Person(models.Model):
user = models.OneToOneField(User, primary_key=True)
title = models.CharField(max_length=3, choices=PERSON_TITLE_CHOICES)
first_name = models.CharField(max_length=100)
Basically, what I want to do, is when I am registering a new user, I'd like to save a Person model, already with the relation to the User.
You have two options here. You can either register a post-save hook for User and create your Person there, or you can create them together. I do the latter. Just make sure you wrap them in a transaction so if one fails, the other does also:
with django.db.transaction.commit_on_success():
user = User(...)
user.save()
person = Person(user = user, ...)
person.save()
Let's say I'm using the default auth.models.User plus my custom Profile and Address models which look like this:
class Profile(models.Model):
user = models.OneToOneField(User)
primary_phone = models.CharField(max_length=20)
address = models.ForeignKey("Address")
class Address(models.Model):
country = CountryField(default='CA')
province = CAProvinceField(default='BC')
city = models.CharField(max_length=80)
postal_code = models.CharField(max_length=6)
street1 = models.CharField(max_length=80)
street2 = models.CharField(max_length=80, blank=True, null=True)
street3 = models.CharField(max_length=80, blank=True, null=True)
Now I want to create a registration form. I could create a ModelForm based on User but that won't include fields for the Profile and Address (which are required). So what's the best way to go about building this form? Should I even use ModelForm at all?
Furthermore, how would I use the same form for editing the complex object? I could easily pass an instance of Profile back to it, which holds references to the necessary Address and Profile objects, but how do I get it to fill in the fields for me?
What about using 3 separate ModelForm. One for Address, one for User, and one for Profile but with :
class ProfileForm(ModelForm):
class Meta:
model = Profile
exclude = ('user', 'address',)
Then, process these 3 forms separately in your views. Specifically, for the ProfileForm use save with commit=False to update user and address field on the instance :
# ...
profile_form = ProfileForm(request.POST)
if profile_form.is_valid():
profile = profile_form.save(commit=False)
# `user` and `address` have been created previously
# by saving the other forms
profile.user = user
profile.address = address
Don't hesitate to use transactions here to be sure rows get inserted only when the 3 forms are valid.
You should look into the officially recommended way to extend the User model first, as seen in the docs, which I believe comes directly from the project manager's personal blog about the subject. (The actual blog article is rather old, now)
As for your actual issue with forms, have a look at the project manager's own reusable django-profiles app and see if perusing the code solves your issue. Specifically these functions and the views in which they are utilized.
Edited to Add:
I've looked into it a bit (as I needed to do so myself). It seems something like so would be sufficient:
# apps.profiles.models
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
...
birth_date = models.DateField(blank=True, null=True)
joined = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = 'user profile'
verbose_name_plural = 'user profiles'
db_table = 'user_profiles'
class Address(models.Model):
user = models.ForeignKey(UserProfile)
...
# apps.profiles.forms
from django import forms
from django.forms import ModelForm
from django.forms.models import inlineformset_factory
from django.contrib.auth.models import User
from apps.profiles.models import UserProfile, Address
class UserForm(ModelForm):
class Meta:
model = User
...
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
...
AddressFormSet = inlineformset_factory(UserProfile, Address)
I was using "..." to snip content in the code above. I have not yet tested this out but from looking through examples and the documentation on forms I believe this to be correct.
Note I put the FK from the Address model to the UserProfile and not the other way around, as in your question. I believe the inline formsets need this to work correctly.
Then of course in your views and templates you will end up treating UserForm, UserProfileForm, and AddressFormSet separately but they can all be inserted into the same form.
I think your are looking for inline formsets with model forms. This helps you to deal with multiple forms on one page and also takes care of foreign key relations.
Update:
Maybe this question helps you too: Django: multiple models in one template using forms