I have Guest model in my app:
class Guest(models.Model):
event = models.ForeignKey(Event, related_name='guests')
contact = models.ForeignKey(Contact, related_name='guests')
attending_status = models.CharField(max_length=32, choices=ATTENDING_CHOICES, default='no_rsvp')
number_of_guests = models.SmallIntegerField(default=0)
comment = models.CharField(max_length=255, blank=True, default='')
updated = models.DateTimeField(blank=True, null=True)
Event and Contact I fill up by myself in Admin when creating a guest. On the site all I want is a guest to fill up the form where he refreshes his attending status, points out number of guests and leaves a comment.
class RSVPForm(forms.Form):
attending = forms.ChoiceField(choices=VISIBLE_ATTENDING_CHOICES, initial='yes', widget=forms.RadioSelect)
number_of_guests = forms.IntegerField(initial=0)
comment = forms.CharField(max_length=255, required=False, widget=forms.Textarea)
How can I save the changes to the Guest model instance? How can I access the guest's id when saving the changes to his profile?
You are probably looking for Django's ModelForms. Instead of subclassing forms.Form in your RSVPForm class, you should subclass forms.ModelForm. Then you can use the features of the model form class to help you achieve what you want (hide some fields, etc). An example is below:
class RSVPForm(forms.ModelForm):
class Meta:
model = Guest
fields = ('attending_status', 'number_of_guests', 'comment')
This will do essentially what you want, but you will need to remember to provide an instance keyword argument to the form constructor in your view function. This argument is the instance of the Guest model you will be updating with the form.
form = RSVPForm(instance=guest_object)
Now calls to the form.save() method will automatically save the new data to this Guest object instance. You just need to make sure that you always pass the instance keyword argument, even when using request.POST:
form = RSVPForm(request.POST, instance=guest_object)
Related
I have some model like below in my blog-like website, I hope different user can query their own data. SO, I need save user id in my model.
However, modeladmin of wagtail only has get_queryset() but no save_model()
class Info(Orderable):
user = models.ForeignKey('auth.User',
on_delete=models.CASCADE,
blank=False, null=True,
related_name='+',)
Is there any way to store user id in wagtail admin panel?
The other way is pre-populate it, I try to do this and it's work well.
def create_view(self, request):
view = super().create_view(request)
self._set_username(view, request)
return view
def _set_username(self, view, request):
if hasattr(view, 'context_data'):
form = view.context_data['form']
form.fields['name'].widget.attrs['value'] = request.user
if you mean (from) admin, yes you can, but if you mean to admin panel from the model class, no you can't, handling the request is job of Views(the controllers) once the URL been requested, the view evaluate many things, one of them is request.user, and this one is an object of User model, you can then ask for id by (requested.user.id).. but of course in the views.py, or wagtail_hooks.py
I am trying to access the username attribute of a Django User object from a Profile object that is related by a OneToOneField.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
username = models.TextField(default=user.username, primary_key=True)
image = models.ImageField(upload_to='images/profile')
header = models.CharField(max_length=64)
slug = AutoSlugField(populate_from='x')
bio = models.CharField(max_length=300, blank=True)
The intent of this is to be able to get a Profile object using a ReactJS frontend by passing the username provided at login back to a profile detail endpoint in a Django API, where the username is the primary key for the endpoint.
path('<pk>/profile/', ShowProfilePageView.as_view(), name='show_profile_page'),
I've tried many different things for the default argument passed to the Profile username attribute, but nothing is working so far. Is this even possible?
Addendum 1: ShowProfilePageView view
class ShowProfilePageView(generics.RetrieveUpdateDestroyAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
model = Profile
I think you can simply override the lookup_field in the View, like this:
class ShowProfilePageView(generics.RetrieveUpdateDestroyAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
model = Profile
lookup_field='user__username'
lookup_url_kwarg='username'
And update the url like this:
path('<str:username>/profile/', ShowProfilePageView.as_view(), name='show_profile_page')
Because through lookup_field, the view will look for the value in User model from Profile model. And lookup_url_kwargs is to map what value it should use from urls. More information can be found in documentation. FYI you should remove username field from Profile model, it should use AutoField(which is the default field for primary key in models).
To access the attribute of one-to-one field you can just do this:
profile = Profile.objects.get(pk='profile_pk') # an object of profile
username = profile.user.username
To search Profile via username:
profile = Profile.objects.get(user=User.objects.get(username='username'))
Thus, you don't need to define username field on Profile class
I am using django to create an inventory management system. There are two models store and retailer. Each retailer can only work in one store, but each store can have many retailer s.
Therefore, store is a ForeignKey in my retailer model. I have registered models in django admin. When I add a retailer I can choose a store.
When I add a store, I would like to be able to add a retailer to a store in the same page I add a store.
class Retailer(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
phone_number = models.IntegerField(default=00000000000)
store = models.ForeignKey(Store,null=True,on_delete=models.CASCADE)
class Store(models.Model):
name = models.CharField(max_length=200)
serial = models.CharField(max_length=200)
number_of_visitors = models.IntegerField(default=0)
it is called inline models:
https://books.agiliq.com/projects/django-admin-cookbook/en/latest/edit_multiple_models.html
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#inlinemodeladmin-objects
And you can find a lot of material about,
But you need something like this:
on your admin.py
#Create a class for inline display:
class RetailerINLINE(admin.TabularInline): #or stacked inline
model = Retailer
extra = 1
class StoreAdmin(admin.ModelAdmin):
.....
inlines = RetailerINLINE,
I'm django learner and I'm trying to design multiple userprofile system.
I recently saw the create_profile function for single userProfile. How can I redesign it to multi user profile creation function?
def create_profile(sender,**kwargs):
if kwargs["created"]:
user_profile=Student.objects.create(user=kwargs["instance"])
post_save.connect(create_profile,sender=User)
Have two models for each profile type. If you want, have them inherit from a base model but you don't need to.
class Student(models.Model):
user = models.ForeignKey(User)
# more fields
class Master(models.Model):
user = models.ForeignKey(User)
# more fields
myuser = User.objects.get(...)
student = Student.objects.create(user=myuser)
master = Master.objects.create(user=myuse
I am using Endpoints-proto-datastore written by Danny Hermes for Google App Engine and need help figuring out how to update an entity.. My model for what I need to update is the following
class Topic(EndpointsModel):
#_message_fields_schema = ('id','topic_name','topic_author')
topic_name = ndb.StringProperty(required=True)
topic_date = ndb.DateTimeProperty(auto_now_add=True)
topic_author = ndb.KeyProperty(required=True)
topic_num_views = ndb.IntegerProperty(default=0)
topic_num_replies = ndb.IntegerProperty(default=0)
topic_flagged = ndb.BooleanProperty(default=False)
topic_followers = ndb.KeyProperty(repeated=True)
topic_avg_rating = ndb.FloatProperty(default=0.0)
topic_total_rating = ndb.FloatProperty(default=0.0)
topic_num_ratings = ndb.IntegerProperty(default=0)
topic_raters = ndb.KeyProperty(repeated=True)
And as you can see, the rating properties have a default of 0. So each time a topic is rated, I need to update each of the rating properties. However, none of my properties is the actual rating being provided by the user. How can i pass in the value the user rated the topic to be able to update the properties in the model? Thanks!
You can do this by having an "alias" property called rating associated with your UserModel:
from endpoints_proto_datastore.ndb import EndpointsAliasProperty
class UserModel(EndpointsModel):
...
def rating_set(self, value):
# Do some validation
self._rating = value
#EndpointsAliasProperty(setter=rating_set)
def rating(self):
return self._rating
This will allow ratings to be sent with UserModels in requests but won't require those ratings to be stored.
You're better off using the OAuth 2.0 token for the user and calling endpoints.get_current_user() to determine who the user is in the request.
Something like a dedicated model for ratings could be much easier:
from endpoints_proto_datastore.ndb import EndpointsUserProperty
class Rating(EndpointsModel):
rater = EndpointsUserProperty(raise_unauthorized=True)
rating = ndb.IntegerProperty()
topic = ndb.KeyProperty(kind=Topic)
and then transactionally retrieving the Topic from the datastore and updating it in a request method decorated by #Rating.method.