I'm a new Django (1.3) user and I'm setting up the typical blog/article application. I have a model in which I'd like to save the current username (to see who created the article). I've implemented advice on this, but my code crashes the server with the message: "NameError: name 'User' is not defined". Here's my model:
from django.db import models
class Resort(models.Model):
name = models.CharField(max_length=300)
description = models.TextField()
location = models.CharField(max_length=300)
ski_hire = models.TextField()
weather = models.TextField()
piste_map = models.TextField()
webcam = models.TextField()
snow = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User)
def __unicode__(self):
return self.name
I have a sneaking suspicion that I need to override the save method in admin.py, but I'm not sure how to do this. Any advice would be greatly appreciated. Thanks!
You need to make sure you import user from django.contrib.auth.models in your models.py when using User in a foreign key.
In your admin.py you can use save_model:
class ResortAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.author = request.user
obj.save()
Maybe You should import User class before assignment?
from django.contrib.auth.models import User
Related
I am doing a group project for a bootcamp and we just started Django for the back-end. We also are using React for front-end. Our project is basically a knockoff reddit.
We have a User model:
`from django.db import models
class User(models.Model):
firstname = models.CharField(max_length=100)
lastname = models.CharField(max_length=100)
email = models.CharField(max_length=100, unique=True)
username = models.CharField(max_length=32, unique=True)
password = models.CharField(max_length=255)
def __str__(self):
return '%s' % (self.username)`
and a Post model:
`from django.db import models
from auth_api.models import User
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
title = models.CharField(max_length=255)
formBody = models.TextField(null=True, blank=True)
imageURL = models.CharField(max_length=200, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)`
Our Post Serializers(pretty unfamiliar with this):
`from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
user = serializers.CharField(required=True)
class Meta:
model = Post
fields = ('id', 'user', 'title', 'formBody', 'imageURL', 'created',)`
And our Post Views:
`from django.shortcuts import render
from rest_framework import generics
from .serializers import PostSerializer
from .models import Post
from auth_api.models import User
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all().order_by('id')
serializer_class = PostSerializer
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all().order_by('id')
serializer_class = PostSerializer`
The idea was when a user created a post their info would be saved with the post so that way when we display the post we could say who created at. Also we could have a user profile that could see all of their posts. I assumed that what would happen is the user info would get saved inside a object in the user column, but the first way we tried only saved the userID and we couldn't access any of the users info. The second way(what we have now) keeps giving us this error: ValueError: Cannot assign "'1'": "Post.user" must be a "User" instance.The 1 is the userID that we pass in from the frontend of the user that created the post. I am unsure of where to go from here and have been stuck for a while on this. Hopefully I provided enough info
I'm using django-guardian and I encountered some issues with the default mixins. And I want to know if there's a better way to do this.
GitHub Link: https://github.com/iaggocapitanio1/django_homepage
Problem:
If I want to limit access at both the model and object levels, using these two mixins (PermissionRequiredMixin, PermissionListMixin) is not a very easy task. Because the permissions_required attribute is overridden. To get around this I had to create a new attribute "object_permission" and do the following:
Model Looks like:
# Create your models here.
from django.db import models
from localflavor.br import models as localModels
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
class Customer(models.Model):
user: User = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
return f'{self.user.first_name} {self.user.last_name}'
class Company(models.Model):
user: User = models.OneToOneField(User, on_delete=models.CASCADE)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='comapnies')
def __str__(self):
return f'{self.user.first_name} {self.user.last_name}'
class Project(models.Model):
name = models.CharField(max_length=100)
owner = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='projects')
class Meta:
permissions = (('read_project', 'Read Project'),)
def __str__(self):
return self.name
class House(models.Model):
rooms = models.IntegerField()
postal_code = localModels.BRPostalCodeField()
project = models.ForeignKey(Project, on_delete=models.CASCADE)
Here I needed to create a new attribute ("object_permission") to limit object-level access
in the View:
class ProjectsListView(PermissionRequiredMixin, PermissionListMixin, ListView):
template_name = 'home/projects.html'
model = models.Project
permission_required = ["homepage.view_project"]
object_permission = ["read_project"]
redirect_field_name = 'next'
login_url = 'login/'
get_objects_for_user_extra_kwargs = {}
def get_object_permission(self, request: HttpRequest = None) -> List[str]:
if isinstance(self.object_permission, str):
perms = [self.object_permission]
elif isinstance(self.object_permission, Iterable):
perms = [p for p in self.object_permission]
else:
raise ImproperlyConfigured("'PermissionRequiredMixin' requires "
"'permission_required' attribute to be set to "
"'<app_label>.<permission codename>' but is set to '%s' instead"
% self.permission_required)
return perms
def get_get_objects_for_user_kwargs(self, queryset):
return dict(user=self.request.user,
perms=self.get_object_permission(self.request),
klass=queryset,
**self.get_objects_for_user_extra_kwargs)
#receiver(post_save, sender=models.Project)
def project_post_save(sender, **kwargs):
"""
Create a Profile instance for all newly created User instances. We only
run on user creation to avoid having to check for existence on each call
to User.save.
"""
project: models.Project = kwargs["instance"]
created: bool = kwargs["created"]
if created:
user = models.User.objects.get(pk=project.owner.user.id)
assign_perm("read_project", user, project)
Am I using the right approach to filter data relative to each user? How do I combine both the page access limitation and the relative data of each user in a class model view?
I have a model called listings and I want staff users to only be able to view, edit, delete listings in the admin panel that they created. Currently staff users can view edit and delete all of the listings
here is my listings/admin.py
from django.contrib import admin
from .models import Listing
class ListingAdmin(admin.ModelAdmin):
list_display =('id','Full_Name','Is_Published','Town_Or_City','District','Region','List_Date')
list_display_links = ('id','Full_Name')
list_editable = ('Is_Published',)
search_fields = ('Full_Name','Town_Or_City','District','Region',)
admin.site.register(Listing, ListingAdmin)
here is my listings/models.py
from django.db import models
from datetime import datetime
from FuneralHomes.models import FuneralHome
class Listing(models.Model):
index = models.ForeignKey(index, on_delete=models.DO_NOTHING,blank=True)
Full_Name = models.CharField(max_length=200)
First_Name = models.CharField(max_length=200)
Last_Name = models.CharField(max_length=200)
Nee = models.CharField(max_length=200, blank=True)
Town_Or_City = models.CharField(max_length=200)
District = models.CharField(max_length=200, blank=True)
Region = models.CharField(max_length=200)
List_Date = models.DateField(max_length=200)
Photo = models.ImageField(upload_to='photos/%Y/%m/%d', blank=True)
Is_Published = models.BooleanField(default=True)
List_Date = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.Full_Name
The admin panel really isn't the place for things like this (as explained in the first paragraph of the Django documentation).
A quick a dirty way of accomplishing what you're trying to do is probably overriding the delete method for this model to check if the user created it. For only listing the user's posts you could utilize the Manager class. Finally, to handle editing, you would have to override the save method to see if it already exists and if the user created it.
you can override get_queryset function and just filter listings related to that user , in this case user can only see his listings .
class ListingAdmin(admin.ModelAdmin):
def get_queryset (self, request):
return Listing.objects.filter(listing_user = request.user)
I have a model:
from django.contrib.auth.models import User
# Create your models here.
class Strategy(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
mod_date = models.DateTimeField(auto_now=True)
strategy_name = models.CharField(max_length=20)
strategy = models.TextField()
position = models.TextField()
I want to get username = "leo".
But in Strategy's user is using user_id.
How to get "models.Strategy.objects.get" or "models.Strategy.objects.filter" using username = "leo"?
Thank you.
Duplicated question Django models filter by foreignkey
Strategy.objects.filter(user__username='leo').first()
or
try:
Strategy.objects.get(user__username='leo')
except Strategy.DoesNotExists():
print 'username Leo does not exists'
Documentation
I have created a custom user model which is working fine.
The problem is when access the user from foreign key, it throws me :
DETAIL: Key (author_id)=(51) is not present in table "auth_user".
My custom user is userauth, clearly the model still looking for the original User model instead of the custom one.
Here is what I did:
#settings.py
AUTH_USER_MODEL = 'userauth.UserAuth'
#models.py
from django.conf import settings
User = settings.AUTH_USER_MODEL
class Post(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
author = models.ForeignKey(User, null=True,blank=True,default=None)
#admin.py
class AdminPost(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if getattr(obj, 'author', None) is None:
obj.author = request.user
obj.save()
I would do something like this instead (don't bother assigning variables):
models.py:
from django.conf import settings
class Post(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
# You don't need 'default=None'
author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)