জ্যাঙ্গো-অ্যালাথ ব্যবহার করার সময় ব্যবহারকারী প্রোফাইল কীভাবে কাস্টমাইজ করা যায়


107

আমার কাছে জ্যাঙ্গো-আল্লাউথ অ্যাপ্লিকেশনটির সাথে একটি জাঙ্গো প্রকল্প রয়েছে। সাইনআপে আমার ব্যবহারকারীর কাছ থেকে অতিরিক্ত ডেটা সংগ্রহ করতে হবে। আমি এখানে একটি অনুরূপ প্রশ্ন জুড়ে এসেছি তবে দুর্ভাগ্যক্রমে, কেউই প্রোফাইল কাস্টমাইজেশন অংশটির উত্তর দেয় না।

ডকুমেন্টেশনdjango-allauth প্রতি সরবরাহিত জন্য :

ACCOUNT_SIGNUP_FORM_CLASS(= None)

একটি কাস্টম ফর্ম শ্রেণীর দিকে নির্দেশকারী একটি স্ট্রিং (উদাহরণস্বরূপ ‘myapp.forms.SignupForm’) যা অতিরিক্ত ইনপুট (যেমন নিউজলেটার সাইনআপ, জন্ম তারিখ) ব্যবহারকারীকে জিজ্ঞাসা করার জন্য সাইনআপের সময় ব্যবহৃত হয়। এই শ্রেণীর একটি ‘save’পদ্ধতি বাস্তবায়ন করা উচিত , সদ্য সাইন আপ হওয়া ব্যবহারকারীটিকে তার একমাত্র পরামিতি হিসাবে গ্রহণ করে।

আমি জাঙ্গোতে নতুন এবং এটি নিয়ে লড়াই করছি। কেউ কি এই জাতীয় কাস্টম ফর্ম শ্রেণির উদাহরণ প্রদান করতে পারেন? এই জাতীয় ব্যবহারকারীর সাথে একটি লিঙ্কের পাশাপাশি আমার কী মডেল ক্লাস যুক্ত করার দরকার আছে ?

উত্তর:


170

মনে করুন আপনি সাইনআপের সময় ব্যবহারকারীকে তার প্রথম / শেষ নামটি জিজ্ঞাসা করতে চান। আপনাকে এই ক্ষেত্রগুলি আপনার নিজের ফর্মের মতো লাগাতে হবে:

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

তারপরে, আপনার সেটিংসে এই ফর্মটি নির্দেশ করে:

ACCOUNT_SIGNUP_FORM_CLASS = 'yourproject.yourapp.forms.SignupForm'

এখানেই শেষ.


10
ধন্যবাদ। এটি মূল লেখকের কাছ থেকে শুনে সর্বদা ভাল is এই তথ্য সংরক্ষণ করার জন্য আমার কি অতিরিক্ত ক্লাস তৈরি করার দরকার আছে বা আল্লাথ স্বয়ংক্রিয়ভাবে সেটির যত্ন নেবে?
শ্রেয়াস

12
এটি আসলে আপনার জিজ্ঞাসা করা তথ্যের উপর নির্ভর করে। যে কোনও ক্ষেত্রে, এটি সমস্ত আল্লৌথের সুযোগের বাইরে। যদি আপনি উপরের উদাহরণ হিসাবে প্রথম / শেষ নামটি জিজ্ঞাসা করেন তবে আপনার অতিরিক্ত মডেলের প্রয়োজন নেই এবং জিনিসগুলি সরাসরি ব্যবহারকারী মডেলটিতে রাখতে পারেন। আপনি যদি ব্যবহারকারীর জন্ম তারিখ, তার প্রিয় রঙ বা যে কোনও বিষয়ে জিজ্ঞাসা করেন তবে এর জন্য আপনাকে নিজের প্রোফাইল মডেল সেটআপ করতে হবে। এটি কীভাবে করবেন সে সম্পর্কে দয়া করে এখানে একবার দেখুন: ডকস.ডজ্যাঙ্গোপ্রজেক্ট
এএন

6
ঠিক আমি যা খুঁজছিলাম - প্রিয় রঙের মতো একটি অতিরিক্ত ক্ষেত্র। আমি যদি প্রিয় রঙটি বলতে আগ্রহী তবে আমি বিশ্বাস করি যে আমার একটি নতুন ইউজারপ্রাইফিল ক্লাস তৈরি করা উচিত এবং তারপরে ব্যবহারকারীকে এক থেকে এক ক্ষেত্র হিসাবে এবং অতিরিক্ত রঙ হিসাবে পছন্দসই রঙটি ব্যবহার করা উচিত। সেক্ষেত্রে, আমি কি এখনও উপরে (সুনির্দিষ্ট রঙ সহ) আপনি ঘোষিত একধরণের সাইনআপফর্ম ব্যবহার করতে পারি এবং এটিতে ACCOUNT_SIGNUP_FORM_CLASS হুক করতে পারি বা আমার নিজের কোডে ফর্মটি তৈরি এবং ডেটা সংরক্ষণ করা দরকার?
শ্রেয়াস

4
অবশ্যই, ACCOUNT_SIGNUP_FORM_CLASS প্রক্রিয়াটি এখনও ব্যবহার করা যেতে পারে। আপনাকে কেবল নিশ্চিত করতে হবে যে সংরক্ষণ () পদ্ধতিটি যথাযথভাবে প্রয়োগ করা হয়েছে যাতে আপনি পছন্দ করতে চান যে কোনও মডেলটিতে পছন্দসই রঙটি সংরক্ষণ করা হয়েছে।
উপার্জনকারী

5
@ স্পেনীয় - ACCOUNT_SIGNUP_FORM_CLASSকাস্টম ব্যবহারকারীর মডেল ক্ষেত্রগুলি সংগ্রহ এবং সংরক্ষণ করার জন্য প্রথম সামাজিক সাইন ইন করার পরে আমি কীভাবে এটি আপ করতে পারি ? এছাড়াও AUTH_USER_MODELগিট থেকে পরিবর্তন করে কাস্টম ব্যবহারকারী মডেল ব্যবহার : পিথিতে github.com/pennersr/django-allauth আপলোড করা হয় না।
বাবু

23

পেনারার দ্বারা প্রস্তাবিত সমাধানটি ব্যবহার করে আমি একটি হ্রাসের সতর্কতা পেয়ে যাচ্ছি:

DeprecationWarning: The custom signup form must offer a def signup(self, request, user) method DeprecationWarning)

এটি কারণ সংস্করণ 0.15 অনুসারে সংরক্ষণের পদ্ধতিটি ডিএফ সাইনআপ (অনুরোধ, ব্যবহারকারী) পদ্ধতির পক্ষে অবচয় করা হয়েছে।

সুতরাং এটি সমাধান করার জন্য, উদাহরণের কোডটি এর মতো হওয়া উচিত:

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

2
@ পেনসেসারের উত্তর এখন signupপরিবর্তে ব্যবহার করার জন্য সম্পাদনা করা হয়েছে save
ফ্লিম 15

18

অন্যান্য উত্তরগুলির কয়েকটি সংমিশ্রিত করার জন্য আমার জন্য এটি কী কাজ করেছে (এর মধ্যে কোনওটিই 100% সম্পূর্ণ এবং DRY নয়)।

ইন yourapp/forms.py:

from django.contrib.auth import get_user_model
from django import forms

class SignupForm(forms.ModelForm):
    class Meta:
        model = get_user_model()
        fields = ['first_name', 'last_name']

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

এবং এর মধ্যে settings.py:

ACCOUNT_SIGNUP_FORM_CLASS = 'yourapp.forms.SignupForm'

এইভাবে এটি মডেল ফর্মগুলি ব্যবহার করে যাতে এটি DRY হয় এবং নতুনটি ব্যবহার করে def signup। আমি রাখার চেষ্টা করেছি 'myproject.myapp.forms.SignupForm'কিন্তু এর ফলে কোনওরকম একটি ত্রুটি হয়েছিল।


'myproject.myapp.forms.SignupForm' এর পরিবর্তে 'yourapp.forms.SignupForm' ব্যবহার করে আমার
পক্ষেও

6

@ শ্রেয়াস: নীচের সমাধানটি সবচেয়ে পরিষ্কার নাও হতে পারে তবে এটি কার্যকর। এটি আরও পরিষ্কার করার জন্য আপনার কাছে কোনও পরামর্শ থাকলে দয়া করে আমাকে জানান।

ডিফল্ট ব্যবহারকারীর প্রোফাইলে অন্তর্ভুক্ত নয় এমন তথ্য যুক্ত করতে প্রথমে ইউর্যাপ / মডেল.পিতে একটি মডেল তৈরি করুন। এ সম্পর্কে আরও জানার জন্য সাধারণ জ্যাঙ্গো ডক্স পড়ুন তবে মূলত:

from django.db import models

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='profile')
    organisation = models.CharField(organisation, max_length=100, blank=True)

তারপরে yourapp / form.py এ একটি ফর্ম তৈরি করুন:

from django import forms

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')
    organisation = forms.CharField(max_length=20, label='organisation')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        # Replace 'profile' below with the related_name on the OneToOneField linking back to the User model
        up = user.profile
        up.organisation = self.cleaned_data['organisation']
        user.save()
        up.save()

ওয়াগটাইল সিএমএস চালানো জ্যাঙ্গো ২.০ অ্যাপ্লিকেশনটির জন্য আমি এটি শেষ করেছি। নিয়মিত সাইন আপের জন্য কাজ করেছেন, তবে সোশ্যাল আথের সাথে এত কম বলে মনে হচ্ছে?
কালোব টালিয়েন

ওয়াগটাইলে ব্যবহারকারীর প্রশাসক পৃষ্ঠায় আমি কীভাবে এই অতিরিক্ত ক্ষেত্রটি যুক্ত করব?
জোশুয়া

5

আপনার মধ্যে users/forms.py:

from django.contrib.auth import get_user_model
class SignupForm(forms.ModelForm):
    class Meta:
        model = get_user_model()
        fields = ['first_name', 'last_name']
    def save(self, user):
        user.save()

Settings.py এ আপনি লিখেছেন:

ACCOUNT_SIGNUP_FORM_CLASS = 'users.forms.SignupForm'

এইভাবে আপনি ব্যবহারকারীর মডেল ক্ষেত্রগুলির সংজ্ঞা দ্বারা DRY নীতিটি ভঙ্গ করবেন না।


4

আমি অনেকগুলি ভিন্ন টিউটোরিয়াল চেষ্টা করেছি এবং সেগুলির মধ্যে কিছু কিছু অনুপস্থিত, অপ্রয়োজনীয় কোডটি পুনরাবৃত্তি করা বা অদ্ভুত জিনিসগুলি করা হচ্ছে, বেলো আমার সমাধানটি অনুসরণ করে যা আমি খুঁজে পেয়েছি এমন সমস্ত অপশনগুলিতে যোগদান করে, এটি কাজ করছে, আমি ইতিমধ্যে এটি প্রযোজনায় ফেলেছি তবে তবুও আমাকে বিশ্বাস করা হচ্ছে না কারণ আমি ফর্মের ভিতরে একটি প্রোফাইল তৈরি এড়াতে ব্যবহারকারীদের সাথে যে ফাংশনগুলি সংযুক্ত করেছিলাম তার মধ্যে প্রথম নাম এবং সর্বশেষ নাম প্রাপ্তির প্রত্যাশা করব তবে আমি পারিনি, এখনই আমি মনে করি এটি আপনাকে সাহায্য করবে।

Models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(max_length=500, blank=True)
    nationality = models.CharField(max_length=2, choices=COUNTRIES)
    gender = models.CharField(max_length=1, choices=GENDERS)

def __str__(self):
    return self.user.first_name


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

Forms.py

class SignupForm(forms.ModelForm):
    first_name = forms.CharField(max_length=100)
    last_name = forms.CharField(max_length=100)

    class Meta:
        model = Profile
        fields = ('first_name', 'last_name', 'nationality', 'gender')

    def signup(self, request, user):
        # Save your user
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

        user.profile.nationality = self.cleaned_data['nationality']
        user.profile.gender = self.cleaned_data['gender']
        user.profile.save()

Settings.py

ACCOUNT_SIGNUP_FORM_CLASS = 'apps.profile.forms.SignupForm'

হাস্যকরভাবে, এটি খুব কয়েকটি জিনিস অনুপস্থিত। প্রোফাইল ক্ষেত্রগুলির কোনও ডিফল্ট নেই, বা এগুলি শূন্য করার অনুমতি দেয় না, তাই create_user_profileডিজাইন করে আপনার সিগন্যাল ব্যর্থ হয়। দ্বিতীয়ত, আপনি এটিকে একটি সিগন্যালে হ্রাস করতে পারেন created, বিশেষত ডিআরওয়াইয়ের সাথে কথা বলার সময়। এবং তৃতীয়ত, আপনি আপনার ভিউতে user.save () কে কল করে একটি প্রোফাইল সেভকে প্রভাবিত করেন, তারপরে প্রকৃত ডেটা দিয়ে আবার প্রোফাইলটি সংরক্ষণ করে।
মেলভিন 24

@ মেলভিয়ান এটি বন্ধনী পরিবর্তে স্কোয়ার ধনুর্বন্ধনীfields = [...] সঙ্গে থাকা উচিত নয় ? fields = (...)
আহতিশাম

এটা পারে, কিন্তু হতে হবে না। মডেলের ক্ষেত্রটি ফর্মটির অংশ হতে পারে কিনা তা যাচাই করতে এটি কেবল পঠনযোগ্য ব্যবহৃত হয়। সুতরাং এটি একটি তালিকা, টিপল বা সেট বা এর কোনও ডেরাইভেটিভ হতে পারে। যেহেতু টিপলগুলি পরিবর্তনীয় নয়, তাই টিপলগুলি ব্যবহার করা এবং দুর্ঘটনাজনিত মিউটেশনগুলি রোধ করা আরও বেশি অর্থবোধ করে। পারফরম্যান্সের দৃষ্টিকোণ থেকে, এই সংগ্রহগুলি কার্যকরভাবে খুব কম প্রভাব ফেলতে পারে। সংগ্রহ একবার দীর্ঘ হয়ে গেলে, excludeপরিবর্তে এটি স্যুইচ করা বুদ্ধিমান হতে পারে ।
মেলভিন

0
#models.py

from django.conf import settings

class UserProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    image = models.ImageField(default='users/default.png', upload_to='users')
    fields = models.ForeignKey('Field' ,null=True ,on_delete=models.SET_NULL)
    category = models.ForeignKey('Category' ,null=True ,on_delete=models.SET_NULL)
    description = models.TextField()
    interests = models.ManyToManyField('Interests')

    ...

   def save(self, *args, **kwargs):
       super().save(*args, **kwargs)

...

def userprofile_receiver(sender, instance, created, *args, **kwargs):
    if created:
        userprofile = UserProfile.objects.create(user=instance)
    else:
        instance.userprofile.save()

post_save.connect(userprofile_receiver, sender=settings.AUTH_USER_MODEL)



 #forms.py

 class SignupForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(SignupForm, self).__init__(*args, **kwargs)
        self.fields['first_name'].widget = forms.TextInput(attrs={'placeholder': 'Enter first name'})
        self.fields['last_name'].widget = forms.TextInput(attrs={'placeholder': 'Enter last name'})

    first_name = forms.CharField(max_length=100)
    last_name = forms.CharField(max_length=100)

    interests  = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, help_text="Choose your interests", queryset=Interests.objects.all())

    image = forms.ImageField(help_text="Upload profile image ")
    fields = forms.ChoiceField(help_text="Choose your fields ")
    category = forms.ChoiceField(help_text="Choose your category")

    class Meta:
        model = UserProfile
        fields = ('first_name', 'last_name',  'name', 'image', 'fields', 'category', 'description', 'phone', 'facebook', 'twitter', 'skype', 'site', 'address', 'interests' ,'biography')
        widgets = {
             ...
            'description': forms.TextInput(attrs={'placeholder': 'Your description'}),
            'address': forms.TextInput(attrs={'placeholder': 'Enter address'}),
            'biography': forms.TextInput(attrs={'placeholder': 'Enter biography'}),
            ....
    }
    def signup(self, request, user):
        # Save your user
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

        user.userprofile.image = self.cleaned_data.get('image')
        user.userprofile.fields = self.cleaned_data['fields']
        user.userprofile.category = self.cleaned_data['category']
        user.userprofile.description = self.cleaned_data['description']
        interests = self.cleaned_data['interests']
        user.userprofile.interests.set(interests)
        user.userprofile.save()


# settings.py or base.py

ACCOUNT_SIGNUP_FORM_CLASS = 'nameApp.forms.SignupForm'

হ্যাঁ, ওটাই. (:


-10

ওয়ানটোওফিল্ড হিসাবে ব্যবহারকারীর সাথে একটি প্রোফাইল মডেল তৈরি করুন

class Profile(models.Model):
    user = models.OneToOneField(User, verbose_name=_('user'), related_name='profiles')
    first_name=models.CharField(_("First Name"), max_length=150)
    last_name=models.CharField(_("Last Name"), max_length=150)
    mugshot = ImageField(_('mugshot'), upload_to = upload_to, blank=True)
    phone= models.CharField(_("Phone Number"), max_length=100)
    security_question = models.ForeignKey(SecurityQuestion, related_name='security_question')
    answer=models.CharField(_("Answer"), max_length=200)
    recovery_number= models.CharField(_("Recovery Mobile Number"), max_length=100)
    city=models.ForeignKey(City,related_name='city', blank=True, null=True, help_text=_('Select your City'))
    location=models.ForeignKey(Country,related_name='location', blank=True, null=True, help_text=_('Select your Location'))

3
ধন্যবাদ, তবে আমি মনে করি না যে এটি কেবল প্রয়োজন। আমার প্রশ্নটি বিশেষত অ্যালাউথ অ্যাপ্লিকেশনটিকে বোঝায়।
শ্রেয়াস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.