簡體   English   中英

Django 中的子表單實例

[英]Child form instance in Django

作為聯系人列表項目的初學者,我無法將聯系人配置文件的實例傳遞給電話列表表單。 當我想向一個人添加多個電話號碼時,我需要將該人的實例加載到添加電話表單中。 當我撥打 function 'addphone' 時,表格會打開一個新電話以獲取聯系人列表。

models.py

class contact_names(models.Model):
    first_name=models.CharField(max_length=20,null=True,blank=True)
    last_name=models.CharField(max_length=20)
    area_l=(
        ('TWO','TWO'),
        .
        .
    )
    dep_l=(
        .
        .
        ('Other','Other'),
    )
    area=models.CharField(max_length=22,choices=area_l,null=True,blank=True)
    DEP =models.CharField(max_length=22, blank=True, null=True, choices=dep_l)
    Subdivision =models.CharField(max_length=20, blank=True, null=True)
    created=models.DateTimeField(auto_now_add=True)
    id=models.UUIDField(default=uuid.uuid4, unique=True,editable=False,primary_key=True)

    def __str__(self) -> str:
        return self.last_name
    def __str__(self) -> str:
        return self.first_name
    

class contact_phone(models.Model):
    p_type=(
        ('Fixed Phone','Fixed Phone'),
         ('Cell Phone','Cell Phone'),
    )
    typep=models.CharField(max_length=15, choices=p_type)
    person=models.ForeignKey(contact_names, on_delete=models.CASCADE)
    phone=models.CharField(max_length=15)
    def __str__(self) -> str:
        return self.phone

views.py

def user(request):
    form=newuser()
    if request.method =='POST':
        form=newuser(request.POST)
        if form.is_valid():
            form.save(commit=True)
            return redirect('contacts')
    return render(request,'apptwo/form_page.html',{'form':form})

def addphone(request,pk):
    ps=contact_names.objects.get(id=pk)
    form=newphone(instance=ps)
    if request.method =='POST':
        form=newphone(request.POST)
        if form.is_valid():
            form.save(commit=True)
            return redirect('contacts')
    return render(request,'apptwo/form_page2.html',{'form':form})

forms.py

class newuser(forms.ModelForm):
    class Meta:
        model= contact_names
       
        fields='__all__'
        
class newphone(forms.ModelForm):
    class Meta:
        model=contact_phone
        fields=['person','typep','phone']

您似乎正在嘗試創建與特定聯系人資料相關聯的電話號碼表單。 在您的 addphone 視圖中,您使用通過 URL 傳入的主鍵 (pk) 正確地從數據庫中獲取聯系人配置文件,但是在視圖的 POST 部分,您正在創建一個新表單而不傳入您之前獲取的聯系人資料。

要解決此問題,您應該更新 addphone 視圖的 POST 部分,以在創建電話號碼表單時使用聯系人配置文件的實例:

if request.method =='POST':
form=newphone(request.POST,instance=ps)
if form.is_valid():
    form.save(commit=True)
    return redirect('contacts')

此外,在您的表單中,您應該將外鍵定義為 person 並且它應該隱藏在表單中,

class newphone(forms.ModelForm):
person = forms.ModelChoiceField(queryset=contact_names.objects.all(), widget=forms.HiddenInput())
class Meta:
    model=contact_phone
    fields=['person','typep','phone']

這樣,當您保存表單時,人員外鍵將自動設置為您傳遞的聯系人實例。

我找到了一種方法,但有一些小問題。 仍然當我想將第一部電話添加到特定的人時,人的下拉列表顯示為“------”,默認形式,但實例沒問題。 當我想添加新的第二部電話時,表格中的電話字段不是空的。 如果有人幫助我,我會很高興。 我很欣賞發布的答案,它有所幫助但沒有完全解決。

視圖.py

def addphone(request,pk):
ps=contact_names.objects.filter(id=pk)
for s in ps:
    pd=s.contact_phone_set.all()
    
if pd.first()== None:
    form=newphone(instance=s)
    form.fields['person'].queryset=ps
else:
    form=newphone(instance=pd.last())
    form.fields['phone'].queryset=None # <------This has no effect!

if request.method =='POST':
    form=newphone(request.POST)
    if form.is_valid():
        form.save(commit=True)
        return redirect('contacts')
return render(request,'apptwo/form_page2.html',{'form':form})enter code here

forms.py

class newphone(forms.ModelForm):
# person = forms.ModelChoiceField(queryset=contact_names.objects.all(), widget=forms.HiddenInput())# #THis didn't Help Since the field is required. 
class Meta:
    model=contact_phone
    p_type=(
    ('Fixed Phone','Fixed Phone'),
     ('Cell Phone','Cell Phone'),)

    fields=['person','typep','phone']
    labels = {
        'typep': '',
    }
    widgets = {
        'typep': forms.RadioSelect(choices=p_type)
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM