Class relationship in Django model - python

My project(Django Rest Framework) is blog app where logged in users can Post some texts and any logged in users can add comment to Posts.
What are the changed I need to make in the Post and Comment class to establish the logic ?
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings
class User(AbstractUser):
#User model
class Post(models.Model):
postdata = models.CharField(max_length=100)
owner = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
class Comment(models.Model):
body = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)

Add a ForeignKey pointing to your Post model in the Comments model:
post = models.ForeignKey('Post', on_delete=models.CASCADE, related_name='comments')
As a good practice, keep using settings.AUTH_USER_MODEL instead of User directly

Related

In Django Models, At Admin Area, how to auto assign the 'requesting' user to one of the foreign key User relation field

In the following mode in my project, I want to assign the author variable of class upon the creation of model, on user end this could be done via request.user but as the class can be only instantiated from the admin area, this doesn't work.
class Blog(models.Model):
title = models.CharField(max_length=300)
content = RichTextField()
author = models.ForeignKey(User, related_name="Author", auto_created= True, on_delete=
models.CASCADE)
date = models.DateTimeField(auto_now_add= True)
The auto_created=… field [Django-doc] is about model inheritance, it does not add the logged in user: the model layer is request unaware, and there is not per se a "logged in user". You thus remodel this to:
from django.conf import settings
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=300)
content = RichTextField()
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
related_name='blogs',
on_delete=models.CASCADE,
editable=False,
)
date = models.DateTimeField(auto_now_add=True)
In the model admin for the Blog model, you can work with:
from django.contrib import admin
#admin.register(Blog)
class BlogAdmin(admin.ModelAdmin):
# …
def save_model(self, request, obj, form, change):
obj.author = request.user
return super().save_model(request, obj, form, change)
Note: The related_name=… parameter [Django-doc]
is the name of the relation in reverse, so from the Blog model to the User
model in this case. Therefore it (often) makes not much sense to name it the
same as the forward relation. You thus might want to consider renaming the Author relation to blogs.
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 User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Django: use a Foreignkey relationship for custom user model

I am writing a webapp where I want to have a general Person table to uniquely identify any person interacting with the website, e.g. to be able to comply to GDPR requests.
Some Persons will should also be Users in the authentication sense.
I'd like to use Person.email for the username.
However, I cannot manage to make authentication / admin interface work.
Simplified models:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
class Person(models.Model):
name = models.CharField(max_length=255, blank=False)
email = models.EmailField(blank=False, unique=True)
class User(AbstractBaseUser, PermissionsMixin):
person = models.OneToOneField(Person, on_delete=models.PROTECT)
USERNAME_FIELD = ...# what to put here?
I found a very old Django issue that seems related:
https://code.djangoproject.com/ticket/21832
Any idea, how to make this work with a foreign key to hold the basic user information?
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
Here you go for correct way of achieving this
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
USERNAME_FIELD = ['email'] # It's mean you can login with your email
class Person(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
Note: If you use AbstractBaseUser models, then you have to write custom model manager.
To avoid writing custom models manager, you should use AbstractUser
class User(AbstractUser):
pass
# here all the required fields like email, name etc item
You can create Person record for the user when a user records creating using django signal:
https://docs.djangoproject.com/en/3.2/topics/signals/

Django admin page not showing user models

My admin page is working fine except when logged in it is not showing any user models. It is hindering my work as I cannot manage users.
I have made custom models as shown below.
Database is MySQL.
models.py
class User(AbstractUser):
is_customer = models.BooleanField(default=False)
is_restaurant = models.BooleanField(default=False)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
food_pref = models.CharField(max_length=10, default='veg')
class Restaurant(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
restaurant_name = models.CharField(max_length=100, blank=False)
Regisrar your models inadmin.py file.
from . models import Model_Name
Then you can register your models in two ways:
I) admin.site.register(Model_Name)
II)
#admin.register(Model_Name)
Class Xyz(admin.ModelAdmin):
pass
Second method gives you more flexibility like list_display, list_filter, date_hierarchy, etc. for customising your Admin section/site.
You can look more about customising admin site at https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#module-django.contrib.admin
Have You registered them in admin.py?
from .models import ModelName
admin.site.register(ModelName)

How do I delete a field from my Django ModelForm?

I'm trying to hide and delete two fields from showing in a form I created in the Django administration page using ModelForm.
I looked at answers that said I should use the "exclude" meta field, but I don't know why it's not working in my case.
Here is my code:
models.py:
class Activity(models.Model):
type = models.CharField(max_length=50, default="")
title = models.CharField(max_length=200, default="")
description = models.CharField(max_length=500)
owner = models.ForeignKey(User, related_name="owner")
college = models.CharField(max_length=200)
location = models.CharField(max_length=200)
room = models.CharField(max_length=200)
startDate = models.DateTimeField(null=True, blank=True)
endDate = models.DateTimeField(null=True, blank=True)
attendee = models.ManyToManyField(Attendee, related_name="attendees",null=True, blank=True)
volunteer = models.ManyToManyField(Volunteer, related_name="volunteers",null=True, blank=True)
I'm trying to exclude the "attendee & volunteer" fields from displaying in the Django administration form.
In admin.py I have:
from django.contrib import admin
from django import forms
from KSUvity.models import Activity
class ActivityForm(forms.ModelForm):
class Meta:
model = Activity
exclude = ['attendee', 'volunteer',]
class ActivityAdmin(admin.ModelAdmin):
exclude = ['attendee', 'volunteer',]
form = ActivityForm
admin.site.register(Activity, ActivityAdmin)
You have to create an admin.py file in your app and register your models
Follow the instuctions
See the example below
from django import forms
from django.contrib import admin
from myapp.models import Person
class PersonForm(forms.ModelForm):
class Meta:
model = Person
exclude = ['name']
class PersonAdmin(admin.ModelAdmin):
exclude = ['age']
form = PersonForm
admin.site.register(Person, PersonAdmin)
You can use either fields or exclude in one class.
In your app admin field add this code.
app_name/admin.py
from django.contrib import admin
class ActivityAdmin(admin.ModelAdmin):
exclude = ('attendee', 'volunteer',)
You have to use ModelAdmin option to exclude fields from form in Django administration, either ModelAdmin.exclude or ModelAdmin.fields. Below is an example:
class ActivityAdmin(admin.ModelAdmin):
exclude = ('attendee', 'volunteer', )
To make it work, you register model like this:
admin.site.register(Activity, ActivityAdmin)
You add this code to admin.py file.

ForeignKey to a Model field?

I want a foreign key relation in my model with the username field in the User table(that stores the user created with django.contrib.auth.forms.UserCreationForm).
This how my model looks:
class Blog(models.Model):
username = models.CharField(max_length=200) // this should be a foreign key
blog_title = models.CharField(max_length=200)
blog_content = models.TextField()
The username field should be the foreign key.The Foreign Key should be with this field
Unless I'm missing something, you can have a ForeignKey to a specific field:
class Blog(models.Model):
username = models.ForeignKey(User, to_field='username')
https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.ForeignKey.to_field
You can't have an ForeignKey to a field, but you can to a row.
You want username which is available through the User model
So:
blog.user.username
If you insist on having blog.username you can define a property like this:
from django.db import models
from django.contrib.auth.models import User
class Blog(models.Model):
user = models.ForeignKey(User)
Then to access the field you want use:
blog.user.username
If you insist on having blog.username you can define a property like this:
from django.db import models
from django.contrib.auth.models import User
class Blog(models.Model):
user = models.ForeignKey(User)
#property
def username(self):
return self.user.username
With that property, you can access username through blog.username.
Note on how to import User
user = ForeignKey('auth.User')
or
from django.contrib.auth.models import User
user = ForeignKey(User)
or the more recommended
from django.conf import settings
user = ForeignKey(settings.AUTH_USER_MODEL)

Categories