Overriding admin form for a model in django - python

Here's my models.py
from multiselectfield import MultiSelectField
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
users = User.objects.values_list('id','username')
authorized = MultiSelectField(choices=users, null=True)
def __str__(self):
return self.question_text
My problem is that while server is running after user register my choices field are not updating till rerun my server.
I did some research and i found solution for that:
https://mschmitt.org/blog/dynamic-django-form-choice-labels/
http://www.ilian.io/django-forms-choicefield-with-dynamic-values/
I have no idea how to override model in forms + i need to override model in django admin forms. any pointers would be great!
thanks in advance

You should not do this at all. If you want to store related objects, you should use a proper database relationship.
In this case, a ManyToManyField to User would be appropriate, since a question can have multiple authorized users and presumably a user can be authorized for multiple questions.

Related

Is it better to make custom registration with editing Django UserCreationForm class or make it on a new table and class?

I wanted to make a Django authentication but I was confused about wichone is better?
is it is better to edit the venv/Lib/site-packages/django/contrib/auth/forms.py file and make my custom form and edit DB on venv/Lib/site-packages/django/contrib/auth/models.py or it's better to make my authentication system with model and views and forms on my application?
You don't need to add django's files. you can inherit there properties.
for example let's say you want to use User model of Django. you can do that in your models.py like following. here you ll get all the fields of Abstract User like first_name, email, passwords etc but you can add your own fields such as technoking in below example
from django.db import models
from django.contrib.auth.models import AbstractUser
import uuid
class User(AbstractUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
technoking = models.BooleanField(default=False)
objects = UserManager()
def __str__(self):
return self.username

showing which post a user liked/saved with python django.

I have trouble to display the ''saved''/''liked'' posts of my users in django/admin. I would like to have a field in the Adminpage to show which user likes which posts. I made an Userprofile model where all extra information (besides the one on the given django admin user Profile) are stored. so here is my model View:
class UserProfile(models.Model):
user = models.OneToOneField(User, null=True)
#likes = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True,default=1, related_name='likes')
likedPosts=models.ManyToManyField('self')
Field1 = models.CharField(max_length=50,default='Sunny')
Field2 = models.CharField(max_length=50,default='')
class Meta:
ordering =['-user']
#def __unicode__(self):
# return self.user.username
User.profile =property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
right now in the liked post field I have only some usernames or "User object"
I tried all kinds of combinations to get the information into the admin page but as you can see I did not make it.
I tried to change the unicode and of course the liked post line. If you need more information please tell me so. I appreciate every kind of help.
django admin isn't really meant to support many to many relationships from both directions in the django admin. However, the link below contains a workaround that I think should address your problem with a better explanation of why many-to-many relationships are only shown from one side by default.
(many-to-many in list display django).
so for everybody who wants to do something similar this worked for me:
class UserProfile(models.Model):
likedPosts = models.ManyToManyField('self',default=None,blank=True)
def __unicode__(self):
return "{0}".format(self.user.likes.all())

Multiple User Types In Django

I am new to Django and trying to create an App with two User Types (Freelancers and Customers). I understand how to create a User profile Class and it works well for me:
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=100, default='')
country = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
This works well for me on a one user type user. But now I am building an app with 2 types of users (freelancers and customers), what is the best approach to get this done. Both users will have different view and info. Should I:
Create 2 different apps, and repeat the normal registeration and login for each.
If I do the above, hope the freelancers when logged in won't access customers view.
How do I add user type to the user profile if I decide to use one app and model for it.
Please I need a step by step beginner approach, or a link to relevant source.
Thanks.
You could try this:
class UserProfile(models.Model):
user = models.ForeignKey(User)
#define general fields
class Freelancer(models.Model):
profile = models.ForeignKey(UserProfile)
#freelancer specific fields
class Meta:
db_table = 'freelancer'
class Customers(models.Model):
profile = models.ForeignKey(UserProfile)
#customer specific fields
class Meta:
db_table = 'customer'
You can then have as many Users as you want from the UserProfile.
You should need just use Groups Django mechanism - you need to create two groups freelancer and let say common and check whether user is in first or second group - then show him appropriate view
To check whether user is in group you can use
User.objects.filter(pk=userId, groups__name='freelancer').exists()
You Could Try extending the Default Django Auth User like this
Create an App with Account or Whatever name you like , then in models.py write like below
class User(AbstractUser):
is_head = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_public = models.BooleanField(default=False)
Add Auth Extended Model in Settings.py
AUTH_USER_MODEL = 'accounts.User'
Migrate your Account app and you are all set with Your User Extended Model.

ValueError: Lookup failed for model referenced by field

I have made Custom User model in my Django project. Here it is:
class CustomUser(User):
avatar = models.ImageField(upload_to='avatars')
about_myself = models.TextField(max_length=300)
USERNAME_FIELD = 'username'
def __str__(self):
return self.username
def is_author(self):
return 'blog.change_post' and 'blog.add_post' in self.get_all_permissions()
And after it, I changed all Foreign Keys of user to new CustomUser model. It works OK. But I make one new migration and django cause error, when I want to migrate it:
ValueError: Lookup failed for model referenced by field blog.Comment.author: main.CustomUser
My blog.Comment model:
class Comment(models.Model):
content = models.TextField()
author = models.ForeignKey(CustomUser)
date_create = models.DateTimeField(auto_now_add=True)
post = models.ForeignKey(Post)
What should I do?
Thanks!
Judging from the code you posted, you might be might be better served by extending the user model rather than replacing it. This pattern is usually called a profile model and works via a one-to-one relationship with User.
Profiles provides application specific fields and behaviors, while allowing User to go about it's usual business unchanged. It doesn't require you to muck around with rewriting auth or even necessarily change your foreign keys.
Here's an example of your code written as a profile:
class Profile(models.Model):
# Link to user :
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
avatar = models.ImageField(upload_to='avatars')
about_myself = models.TextField(max_length=300)
def __str__(self):
return self.user.username
def is_author(self):
return 'blog.change_post' and 'blog.add_post' in self.user.get_all_permissions()
Comment model:
class Comment(models.Model):
content = models.TextField()
author = models.ForeignKey(settings.AUTH_USER_MODEL)
date_create = models.DateTimeField(auto_now_add=True)
post = models.ForeignKey(Post)
# How to access the profile:
def check_author(self):
self.author.profile.is_author()
You'll also want to add a signal to create a new profile when a user is registered:
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_profile_for_new_user(sender, created, instance, **kwargs):
if created:
profile = Profile(user=instance)
profile.save()
Django docs on extending users.
If a profile approach doesn't work for you, try inheriting from AbstractUser or AbstractBaseUser instead of User. The abstract models provide the same basic functionality as User and are the preferred technique for recent Django versions.
There are a handful of additional steps however, check out the docs on creating custom users for a run down.

Multiple model forms with (foreign key) in multiple pages. Django

This is my first Question ever on StackOverflow, so bear with me for my mistakes.
Now, to the question!
I am currently making website in django and It has multiple models which are linked to one parent model. Now I want to create a multiple page form to include all this models. How to do that???
here's problem in detail:
models.py
class Profile(models.Model):
user = models.OneToOneField(User)
first_name = odels.CharField(
max_length=255, validators=ONLY_LETTERS_VALIDATOR)
last_name = odels.CharField(
max_length=255, validators=ONLY_LETTERS_VALIDATOR)
# And some other fields
class YMHTMobile(models.Model):
profile = models.ForeignKey(Profile)
mobile = models.CharField(max_length=10, validators=ONLY_DIGITS_VALIDATOR)
is_active = models.BooleanField(default=True)
def __unicode__(self):
return '%s' % self.mobile
class Meta:
verbose_name_plural = 'Mobile Details'
# some more models with foreign key as profile
Now I want to create a Multiple page form with all these models(like one model form in one page and click next for another form)
How do I do that??
Use the Form Wizard contrib app.
UPDATE: Form Wizard was moved from django 1.8 to separate project - Django Form Tools.

Categories